快手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);
 
 
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值