快手2020校園招聘秋招筆試--算法B試卷

四個編程題總體算比較簡單,基本都在LeetCode出現過。但是我的速度太慢了,還要加油啊ヾ(◍°∇°◍)ノ゙
牛客快手2020校園招聘秋招筆試–算法B試卷

合法數獨

給定一個數獨板的輸入,確認當前的填法是否合法。
合法的輸入需要滿足以下三個條件:

  1. 每一行的9個格子中是1-9的9個數字,且沒有重複
  2. 每一列的9個格子中是1-9的9個數字,且沒有重複
  3. 9個3*3的小格子中是1-9的9個格子,且沒有重複
    :開始意思弄錯了判斷的是能不能填滿81個數,爛費了好多時間。結果是隻要判斷當前的,就很難受。
    set判斷當前值,不包含則加入當前值,包含代表重複,則返回false
obj.dfs(s,0,0);
System.out.println(obj.answer); 
判斷81個能否都填滿。
 import java.util.*;
 public class Main {
    boolean answer = false;
    private boolean get(char str[][]){ 
        for (int x=0;x<9;x++){
            Set<Character> set = new HashSet<>();
            for (int y = 0; y < 9; y++) {
                if (str[x][y] != 'X' && !set.contains(str[x][y]))
                    set.add(str[x][y]);
                else if(set.contains(str[x][y]))
                    return false;
            }
        }
        for (int x=0;x<9;x++){
            Set<Character> set = new HashSet<>();
            for (int y = 0; y < 9; y++) {
                if (str[y][x] != 'X' && !set.contains(str[y][x]))
                    set.add(str[y][x]);
                else if(set.contains(str[y][x]))
                    return false;
            }
        }
        for (int x=0;x<3;x++){
            for (int y=0;y<3;y++){
                Set<Character> set = new HashSet<>();
                for (int i = 0; i < 3; i++) {
                    for (int j = 0; j < 3; j++) {
                        if(str[x*3+i][y*3+j]!='X' && !set.contains(str[x*3+i][y*3+j]))
                            set.add(str[x*3+i][y*3+j]);
                        else if(set.contains(str[x*3+i][y*3+j]))
                            return false;
                    }
                }
            }
        }
        return true;
    }
    public static void main(String[] args) {
        Main obj = new Main();
        String []mm=new String[9];
        char[][] s= new char [9][9];
        Scanner scanner = new Scanner(System.in);
        for (int i = 0; i < 9; i++) {
            mm[i]=scanner.nextLine();
            for (int j = 0; j < 9; j++) {
                s[i][j]=mm[i].charAt(j) ;
            }
        }
 
//            obj.dfs(s,0,0);
//            System.out.println(obj.answer); 
        System.out.println(obj.get(s));
    }
	private void dfs(char [][] str,int x,int y){
        if (y==9){
            x++;
            y=0;
        }
        if(x>8){
            this.answer=true;
            return  ;
        }
        while (x<=8){
            if(str[x][y]=='X')
                break;
             y++;
             if (y==9){
                x++;
                y=0;
             }
            if(x>8){
                this.answer=true;
                return  ;
            }
        }
        Set<Character> set = new HashSet<>();
        for (int i = 1; i <= 9; i++) set.add((char)(i+'0'));
        for (int i = 0; i < 9; i++) {
            if (str[i][y] != 'X' && set.contains(str[i][y]))
                set.remove(str[i][y]);
        }
        for (int i = 0; i < 9; i++) {
            if (str[x][i] != 'X' && set.contains(str[x][i]))
                set.remove(str[x][i]);
        }
        int x1=x/3 * 3,y1=y/3 * 3;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (str[x1+i][y1+j] != 'X' && set.contains(str[x1+i][y1+j])) {
                    set.remove(str[x1 + i][y1 + j]);
                }
            }
        }
        for (Character character : set){
            str[x][y]=character;
            dfs(str,x,y+1);
            str[x][y]='X';
        }
        return ;
    }
}

分解質因數

我們知道每一個大於1的整數都一定是質數或者可以用質數的乘積來表示,如10=25。現在請設計一個程序,對於給定的一個(1,N] 之間的正整數(N取值不超過10萬),你需要統計(1,N] 之間所有整數的質數分解後,所有質數個數的總個數。舉例,輸入數據爲6,那麼滿足(1,6] 的整數爲2,3,4,5,6,各自進行質數分解後爲:2=>2,3=>3,4=>22,5=>5,6=>2*3。對應的質數個數即爲1,1,2,1,2。最後統計總數爲7
輸入描述:
輸入數據包含1行,爲一個大於1的整數(不超過10萬)。
輸出描述:
輸出小於等於該數的所有整數質數分解後的總個數。
示例1
輸入

6

輸出

7

:肯定有更好的方法不過我是暴力的…當時當算超時了就直接往數組存打出來的質數,然後優化後面的找質因子的代碼,好結果都沒必要,可能100000太小了把。

public class Main {
    public static void main(String[] args) {
        List<Integer> set = new ArrayList<>();
        for (int i = 2; i < 100000; i++) {
            int flag=0;
            for (int j = 2; j <= (int)Math.sqrt(i); j++) {
                if(i%j==0) {
                    flag=1;
                    break;
                }
            }
            if(flag == 0)
                set.add(i);
        }
        int n = 100000,sum=0;
        Scanner scanner = new Scanner(System.in);
        n=scanner.nextInt();
        scanner.close();
        for (int i=2;i<=n;i++){
            int ii=i;
            while (ii!=1){
                for (Integer a: set){
                    if(ii%a==0){
                        ii/=a;
                        sum++;
                        break;
                    }
                    if(a>ii)
                        break;
                }
            }
        }
        System.out.println(sum);
    }
}

Levenshtein distance

已知兩個字符串strA和strB,求將strA轉換成strB所需的最小編輯操作次數。許可的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。
輸入描述:
任意字符串strA和strB,其中第一行爲strA,第二行爲strB
輸出描述:
最小編輯操作次數
示例1
輸入

FreshMeat
FishAndMeat 

輸出

 5 

: 演算找出規律(說起來輕鬆做起來難o(╥﹏╥)o)
1 當前字符相等strA[j] 等於 strB[i] ,則當前dp值爲左上角dp值
2 字符不等,左dp值 != 上dp值, 當前dp值爲min(左dp,上dp)+1
3 字符不等,左dp值 等於 上dp值, 當前dp值爲 左上角dp值 +1 此種容易想錯

// FreshMeat
// FishAndMeat
// 0 1 2 3 4 5 6 7 8 9
// 1 0 1 2 3 4 5 6 7 8
// 2 1 1 2 3 4 5 6 7 8
// 3 2 2 2 2 3 4 5 6 7
// 4 3 3 3 3 2 3 4 5 6
// 5 4 4 4 4 3 3 4 5 6
// 6 5 5 5 5 4 4 4 5 6
// 7 6 6 6 6 5 5 5 5 6
// 8 7 7 7 7 6 5 6 6 6
// 9 8 8 7 8 7 6 5 6 7
// 10 9 9 8 8 8 7 6 5 6
// 11 10 10 9 9 9 8 7 6 5

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String strA = scanner.nextLine();
        String strB = scanner.nextLine();
        scanner.close();
        int up=0,down=0;
        int lenA = strA.length();
        int lenB = strB.length();
        int dp[][]=new int[lenB+1][lenA+1];
        dp[0][0]=0;
        for (int i = 0; i <= lenB; i++) dp[i][0]=i;
        for (int i = 0; i <= lenA; i++) dp[0][i]=i;

        for (int ii = 1; ii <= lenB; ii++) {
            int i=ii-1;
            for (int jj=1;jj<=lenA;jj++){
                int j=jj-1;
                if(strB.charAt(i) == strA.charAt(j)){
                    dp[ii][jj]=dp[i][j];// 相等爲左上角dp
                }else if(dp[ii][j] == dp[i][jj]){
                    dp[ii][jj]=dp[i][j]+1;//上方的值 == 左方的值 當前值=左上值+1
                }else {
                    //上方的值 != 左方的值 當前值=min(左值,上值)+1
                    dp[ii][jj]=Math.min(dp[ii][j],dp[i][jj])+1;
                }
            }
        }
        System.out.println(dp[lenB][lenA]);

    }
}

單詞反轉

輸入一個英文句子, 詞之間有1個或者若干個空格,句子以英文標點".“結尾。
要求顛倒該句子中的詞語順序,並且詞之間有且只有一個空格,結尾仍然是”.",結尾的"."與前一個單詞之間無空格。
輸入描述:

I     love   you  .

輸出描述:

you love I.

示例1
輸入

 I  love     you.

輸出

you love I.

題目本意應該是雙指針遍歷,不過有api(逃)

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String a = scanner.nextLine();
        int flag = 0;
        for (int i=a.length()-1;i>=0;i--){
            if(a.charAt(i) == '.'){
                a=a.substring(0,i );
                break;
            }
        }
        String b="";
        String str[]=a.trim().split(" +");
        for(int i=str.length-1;i>0;i--){
            b=b+str[i]+" ";
        }
        b=b+str[0]+".";
        System.out.println(b);
 
 
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章