笔试练习:day1

第一题:组队竞赛
思路分析:
先将输入的数字排为升序,每组中的第二大数字要尽可能大,因此每次分组的时后都选择一个最大的和仅次于最大的数字分到一组,这样的分组方式能够保证在排为升序后的数组了,每组的第二大的数字都是排在后面比较大的数字.
在这里插入图片描述
因此我们只需要找出每一个队伍里第二大的数字即可,观察排序后的数字:
在这里插入图片描述
代码:

   public static void main(String[] args){
    
    
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] arr = new int[n*3];
        for(int i = 0; i<3*n; i++){
    
    
            arr[i] = scanner.nextInt();
        }
        //排序
        Arrays.sort(arr);
        int mid = 0;
        int sum = 0;
        for(int i =0; i < n;i++){
    
    
            mid = arr.length-2*(i+1);
            sum+=arr[mid];
        }
        System.out.println(sum);


    }

这段代码会报错,原因在于当数字过大的时候,int类型的sum在累加之后数字int无法完整保存,会溢出:
在这里插入图片描述
因此,要将int改成long:

  public static void main(String[] args){
    
    
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] arr = new int[n*3];
        for(int i = 0; i<3*n; i++){
    
    
            arr[i] = scanner.nextInt();
        }
        //排序
        Arrays.sort(arr);
        int mid = 0;
        long sum = 0;
        for(int i =0; i < n;i++){
    
    
            mid = arr.length-2*(i+1);
            sum+=arr[mid];
        }
        System.out.println(sum);


    }

在这里插入图片描述
第二题:删除公共字符
方法1暴力删除:
遍历第二个字符串(str2),同时如果str2里的字符存在第一个字符串(str1)里,就将这个字符用后面的字符来覆盖达到删除的效果.

在这里插入图片描述

 public static void main(String[] args) {
    
    
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) {
    
     // 注意 while 处理多个 case
            String a = in.nextLine();
            char[] chars1 =a.toCharArray();
            String b = in.nextLine();
            char[] chars2 =b.toCharArray();
            int len1 = chars1.length;
            int len2 = chars2.length;
            for(int j = 0; j < len2;j++){
    
    
                for(int i = 0; i <len1; i++){
    
    
                    if(chars1[i] == chars2[j]){
    
    
                        for(int k = i;k<len1-1;k++){
    
    //找到相同的字符之后,覆盖
                            chars1[k] = chars1[k+1];
                        }
                        len1--;
                    }
                }
            }
            a = new String (chars1,0,len1);
            System.out.println(a);
        }
    }

需要注意的地方:
1.将字符串转为字符数数组
2.在覆盖时是从第二层循环的i处开始覆盖,为了确保将str2里的第j字符在str1里删除,因此第三层循环不能改变i的值,而是要用另外的变量来记录i的值,这样才能达到在确保在第i个值成功删除后,在i的后面如果还有这个字符i可以继续进入到第三三层循环继续删除.
3.进入第三层循环结束后,str1的长度要减1
暴力删除要移动字符,而且有多层循环的嵌套,时间复杂度O(N*3),效率太低.
4.覆盖是arr[i] = arr[i+1],因此第三层循环的结束条件是str1.length-1,否则会出现数组越界访问

方法二哈希映射:
在这里插入图片描述

 public static void main(String[] args) {
    
    
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) {
    
     // 注意 while 处理多个 case
            String s1 = in.nextLine();
            String s2 = in.nextLine();

            //创建hashmap
            HashMap<Character,Integer> map  =new HashMap<>();

            //循环遍历第二个字符串,将字符都放进哈希表里
            for(int i= 0; i < s2.length();i++){
    
    
                if(map.get(s2.charAt(i)) == null){
    
    //没有这个字符
                    map.put(s2.charAt(i),1);
                }else{
    
    //有这个字符,value值+1
                map.put(s2.charAt(i), map.get(s2.charAt(i)+1));
                }
            }
             //遍历第一个字符串
            String s = "";
            for(int i= 0; i<s1.length();i++){
    
    
                if(map.get(s1.charAt(i)) ==null){
    
    //如果map里不存在这个字符,就将这个字符拼接起来
                    s+=s1.charAt(i);
                }
            
        }
         System.out.println(s);
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_62160964/article/details/127460340
今日推荐