[Leetcode Weekly Contest]337

链接:LeetCode

[Leetcode]6319. 奇偶位数

给你一个 正 整数 n 。
用 even 表示在 n 的二进制形式(下标从 0 开始)中值为 1 的偶数下标的个数。
用 odd 表示在 n 的二进制形式(下标从 0 开始)中值为 1 的奇数下标的个数。
返回整数数组 answer ,其中 answer = [even, odd] 。

遍历即可。

class Solution {
    public int[] evenOddBit(int n) {
        int even = 0, odd = 0;
        for(int i=0;i<=10;++i) {
            int val = 1 << i;
            if((n & val) != 0) {
                if((i & 1) != 0) odd++;
                else even++;
            }
        }
        return new int[]{even, odd};
    }
}

[Leetcode]6322. 检查骑士巡视方案

骑士在一张 n x n 的棋盘上巡视。在有效的巡视方案中,骑士会从棋盘的 左上角 出发,并且访问棋盘上的每个格子 恰好一次 。
给你一个 n x n 的整数矩阵 grid ,由范围 [0, n * n - 1] 内的不同整数组成,其中 grid[row][col] 表示单元格 (row, col) 是骑士访问的第 grid[row][col] 个单元格。骑士的行动是从下标 0 开始的。
如果 grid 表示了骑士的有效巡视方案,返回 true;否则返回 false。
注意,骑士行动时可以垂直移动两个格子且水平移动一个格子,或水平移动两个格子且垂直移动一个格子。下图展示了骑士从某个格子出发可能的八种行动路线。

遍历即可。

class Solution {
    public boolean checkValidGrid(int[][] grid) {
        HashMap<Integer, int[]> posititon = new HashMap<Integer, int[]>();
        if(grid[0][0]!=0) return false;
        int n = grid.length, m = grid[0].length;
        for(int i=0;i<n;++i) {
            for(int j=0;j<m;++j) {
                posititon.put(grid[i][j], new int[]{i,j});
            }
        }
        for(int pos=1;pos<n*m;++pos) {
            int dx = Math.abs(posititon.get(pos)[0] - posititon.get(pos-1)[0]);
            int dy = Math.abs(posititon.get(pos)[1] - posititon.get(pos-1)[1]);
            if((dx == 1 && dy == 2) || (dx == 2 && dy == 1)) continue;
            return false;
        }
        return true;
    }
}

[Leetcode]6352. 美丽子集的数目

给你一个由正整数组成的数组 nums 和一个 正 整数 k 。
如果 nums 的子集中,任意两个整数的绝对差均不等于 k ,则认为该子数组是一个 美丽 子集。
返回数组 nums 中 非空 且 美丽 的子集数目。
nums 的子集定义为:可以经由 nums 删除某些元素(也可能不删除)得到的一个数组。只有在删除元素时选择的索引不同的情况下,两个子集才会被视作是不同的子集。

动态规划。如果两个数模 k 不同余,那么必然无法相差 k。所以我们可以按照模 k 的结果分组,每一组用哈希表/有序集合统计元素及其出现次数。
每一组怎么思考呢?按照 key 从小到大排序后(设这些 key 组成了数组 g),相邻的 key 如果相差 k,那么不能同时选

class Solution {
    public int beautifulSubsets(int[] nums, int k) {
        var groups = new HashMap<Integer, TreeMap<Integer, Integer>>();
        for (int x : nums)
            groups.computeIfAbsent((x % k), key -> new TreeMap<>()).merge(x, 1, Integer::sum);
        int ans = 1;
        for (var g : groups.values()) {
            int m = g.size();
            var f = new int[m + 1];
            f[0] = 1;
            int i = 1, pre = 0;
            for (var e : g.entrySet()) {
                int cur = e.getKey();
                if (i > 1 && cur - pre == k)
                    f[i] = f[i - 1] + f[i - 2] * ((1 << e.getValue()) - 1);
                else
                    f[i] = f[i - 1] << e.getValue();
                pre = cur;
                ++i;
            }
            ans *= f[m];
        }
        return ans - 1; // -1 去掉空集
    }
}

[Leetcode]6321. 执行操作后的最大 MEX

给你一个下标从 0 开始的整数数组 nums 和一个整数 value 。
在一步操作中,你可以对 nums 中的任一元素加上或减去 value 。

  • 例如,如果 nums = [1,2,3] 且 value = 2 ,你可以选择 nums[0] 减去 value ,得到 nums = [-1,2,3] 。

数组的 MEX (minimum excluded) 是指其中数组中缺失的最小非负整数。

  • 例如,[-1,2,3] 的 MEX 是 0 ,而 [1,0,3] 的 MEX 是 2 。

返回在执行上述操作 任意次 后,nums 的最大 MEX 。

贪心.

class Solution {
    public int findSmallestInteger(int[] nums, int m) {
        var cnt = new HashMap<Integer, Integer>();
        for (int x : nums)
            cnt.merge((x % m + m) % m, 1, Integer::sum); // cnt[(x%m+m)%m]++
        int mex = 0;
        while (cnt.merge(mex % m, -1, Integer::sum) >= 0) // cnt[mex%m]-1 >= 0
            ++mex;
        return mex;
    }
}

参考:LeetCode

posted @ 2023-03-20 20:43  Jamest  阅读(22)  评论(0编辑  收藏  举报