LeetCode第 302 场周赛 (Java)

第一题:6120. 数组能形成多少数对

给你一个下标从 0 开始的整数数组 nums 。在一步操作中,你可以执行以下步骤:

从 nums 选出 两个 相等的 整数
从 nums 中移除这两个整数,形成一个 数对
请你在 nums 上多次执行此操作直到无法继续执行。

返回一个下标从 0 开始、长度为 2 的整数数组 answer 作为答案,其中 answer[0] 是形成的数对数目,answer[1] 是对 nums 尽可能执行上述操作后剩下的整数数目。

示例 1:

输入:nums = [1,3,2,1,3,2,2]
输出:[3,1]

public int[] numberOfPairs(int[] nums) {
        Arrays.sort(nums);
        int len=nums.length;
        int[] ans=new int[2];
        for (int i = 1; i < len; i++) {
            if (nums[i]==nums[i-1]){
                i++;
                ans[0]++;
            }
        }
        ans[1]=len-2*ans[0];
        return ans;
    }

  首先要对数组进行排序,然后遍历数组,判断当前的数是否和前一个数相同,若相同,则i应该手动加一,当作删除当前数对,并将记录数对数的ans[0]++,最后ans[1]是数组长度-2*数对数即ans[0]。

第二题:6164. 数位和相等数对的最大和

给你一个下标从 0 开始的数组 nums ,数组中的元素都是正整数。请你选出两个下标 i 和 j(i != j),且 nums[i] 的数位和 与  nums[j] 的数位和相等。

请你找出所有满足条件的下标 i 和 j ,找出并返回 nums[i] + nums[j] 可以得到的 最大值 。

示例 1:

输入:nums = [18,43,36,13,7]
输出:54
 

public int maximumSum(int[] arr) {
        Node[] nodes=new Node[arr.length];
        for (int i = 0; i < arr.length; i++) {
            nodes[i]=new Node(arr[i],sum(arr[i]));
        }
        Arrays.sort(nodes);
        int max=-1;
        for (int i = 1; i <arr.length ; i++) {
            if (nodes[i].sum==nodes[i-1].sum){
                int a=nodes[i].n;
                int b=nodes[i-1].n;
                max=Math.max(a+b,max);
            }
        }
        return max;
    }
    public static int sum(int x){
        char[] c=String.valueOf(x).toCharArray();
        int t=0;
        for (int i = 0; i < c.length; i++) {
            t+=c[i]-'0';
        }
        return t;
    }

    static class Node implements Comparable<Node>{
        int n,sum;

        public Node(int n, int sum) {
            this.n = n;
            this.sum = sum;
        }

        @Override
        public int compareTo(Node o) {
            if (this.sum==o.sum) return o.n-this.n;
            return this.sum-o.sum;
        }
    }

需要将各个数与自身的数位和封装成一个对象,然后按照数位和的大小进行排序,以便到相同数位和的数,遍历nodes,判断当前node的数位和与前一个node的数位和是否相等,若相等则将两个数的和与结果max进行比较更新。

第三题:6121. 裁剪数字后查询第 K 小的数字

给你一个下标从 0 开始的字符串数组 nums ,其中每个字符串 长度相等 且只包含数字。

再给你一个下标从 0 开始的二维整数数组 queries ,其中 queries[i] = [ki, trimi] 。对于每个 queries[i] ,你需要:

将 nums 中每个数字 裁剪 到剩下 最右边 trimi 个数位。
在裁剪过后的数字中,找到 nums 中第 ki 小数字对应的 下标 。如果两个裁剪后数字一样大,那么下标 更小 的数字视为更小的数字。
将 nums 中每个数字恢复到原本字符串。
请你返回一个长度与 queries 相等的数组 answer,其中 answer[i]是第 i 次查询的结果。

提示:

裁剪到剩下 x 个数位的意思是不断删除最左边的数位,直到剩下 x 个数位。
nums 中的字符串可能会有前导 0 。

示例 1:

输入:nums = ["102","473","251","814"], queries = [[1,1],[2,3],[4,2],[1,2]]
输出:[2,2,1,0]

public int[] smallestTrimmedNumbers(String[] s, int[][] q) {
        int[] res=new int[q.length];
        for (int i = 0; i < q.length; i++) {
            Node[] node=new Node[s.length];
            for (int j = 0; j < s.length; j++) {
                String ss=s[j].substring(s[j].length()-q[i][1]);
                node[j]=new Node(ss,j);
            }
            Arrays.sort(node);
            res[i]=node[q[i][0]-1].idx;
        }
        return res;
    }
    static class Node implements Comparable<Node>{
        int idx;
        String n;

        public Node(String n, int idx) {
            this.n = n;
            this.idx = idx;
        }

        @Override
        public int compareTo(Node o) {
            if (this.n==o.n) return this.idx-o.idx;
            return this.n.compareTo(o.n);
        }
    }

与第二题相类似,需要将剪切后的字符串数组与自身的索引值封装成对象,然后根据字符串的字典序大小进行排序,以便找到第k小的数,这里有个小细节,就是第k小的数就是排序后索引为k-1的node的idx。

第四题:6122. 使数组可以被整除的最少删除次数

给你两个正整数数组 nums 和 numsDivide 。你可以从 nums 中删除任意数目的元素。

请你返回使 nums 中 最小 元素可以整除 numsDivide 中所有元素的 最少 删除次数。如果无法得到这样的元素,返回 -1 。

如果 y % x == 0 ,那么我们说整数 x 整除 y 。

示例 1:

输入:nums = [2,3,2,4,3], numsDivide = [9,6,9,3,15]
输出:2
 

public int minOperations(int[] arr, int[] d) {
        Arrays.sort(arr);
        int[] f = f(d);
        for (int i = 0; i < arr.length; i++) {
            if (i>0&&arr[i]==arr[i-1])continue;
            int cnt=0;
            while (cnt<f.length&&f[cnt]%arr[i]==0)cnt++;
            if (cnt==f.length) return i;
        }
        return -1;
    }
    public static int[] f(int[] d){
        TreeSet<Integer> set=new TreeSet<>();
        for (int i = 0; i < d.length; i++) {
            set.add(d[i]);
        }
        int[] arr=new int[set.size()];
        int cnt=0;
        for (int i:set){
            arr[cnt]=i;
            cnt++;
        }
        return arr;
    }

此题是先将数组排序,更容易找到最小元素,遍历数组,若当前数与前一个数相同则跳过本次循环,否则判断当前数是否能整除数组d中的所有数,如果可以直接返回当前数的索引值,遍历完后没有找到符合条件的数,则返回-1。这里我先对d数组进行去重和排序,提高效率!

总结:本次周赛难度适中,题目类型相似

猜你喜欢

转载自blog.csdn.net/TerryProgrammer/article/details/125831240