6319. Number of Even and Odd Bits

给你一个 正 整数 n 。

用 even 表示在 n 的二进制形式(下标从 0 开始)中值为 1 的偶数下标的个数。

用 odd 表示在 n 的二进制形式(下标从 0 开始)中值为 1 的奇数下标的个数。

返回整数数组 answer ,其中 answer = [even, odd] 。

测试样例

输入:n = 17

输出:[2,0]

解答:按照题意计算奇偶二进制情况

class Solution {
    public int[] evenOddBit(int n) {
        int[] res = {0,0};
        for (int i = 0; i < 31; ++i) {
            int m = (n >> i) & 1;
            res[i % 2] += m;
        }
        return res;
    }
}

6322. Check Knight Tour Configuration

骑士在一张 n x n 的棋盘上巡视。在有效的巡视方案中,骑士会从棋盘的 左上角 出发,并且访问棋盘上的每个格子 恰好一次 。

给你一个 n x n 的整数矩阵 grid ,由范围 [0, n * n - 1] 内的不同整数组成,其中 grid[row][col] 表示单元格 (row, col) 是骑士访问的第 grid[row][col] 个单元格。骑士的行动是从下标 0 开始的。

如果 grid 表示了骑士的有效巡视方案,返回 true;否则返回 false。

注意,骑士行动时可以垂直移动两个格子且水平移动一个格子,或水平移动两个格子且垂直移动一个格子。下图展示了骑士从某个格子出发可能的八种行动路线。

测试样例:

输入:grid = [[0,11,16,5,20],[17,4,19,10,15],[12,1,8,21,6],[3,18,23,14,9],[24,13,2,7,22]]

输出:true

解答: 按照顺序搜索棋盘。保证骑士从0,0点开始,然后每一步都能达到。

class Solution {
    public boolean checkValidGrid(int[][] grid) {
        int n = grid.length;
        List<int[]> pos = new ArrayList<>();
        for (int i = 0; i < n * n; ++i) {
            pos.add(null);
        }
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                pos.set(grid[i][j], new int[]{i, j});
            }
        }
        if (pos.get(0)[0] != 0 || pos.get(0)[1] != 0) {
            return false;
        }
        int[] last = {0,0};
        for (int i = 1; i < pos.size(); ++i) {
            int[] cur = pos.get(i);
            if (!isValid(Math.abs(cur[0] - last[0]), Math.abs(cur[1] - last[1]))) {
                return false;
            }
            last = cur;
        }
        return true;
    }

    private boolean isValid(int x, int y) {
        return (x == 2 && y == 1) || (x == 1 && y == 2);
    }
}

6352. The Number of Beautiful Subsets

给你一个由正整数组成的数组 nums 和一个 正 整数 k 。

如果 nums 的子集中,任意两个整数的绝对差均不等于 k ,则认为该子数组是一个 美丽 子集。

返回数组 nums 中 非空 且 美丽 的子集数目。

nums 的子集定义为:可以经由 nums 删除某些元素(也可能不删除)得到的一个数组。只有在删除元素时选择的索引不同的情况下,两个子集才会被视作是不同的子集。

测试样例

输入:nums = [2,4,6], k = 2

输出:4

解释:

数组 nums 中的美丽子集有:[2], [4], [6], [2, 6] 。可以证明数组 [2,4,6] 中只存在 4 个美丽子集。

解答:这道题目,看到nums.length的范围小于20,我以为可以直接暴力枚举计算的,但是被卡常了。不知道是不是Java的问题。换了一下算法实现细节,就能过了。

class Solution {
    public int beautifulSubsets(int[] nums, int k) {
        Arrays.sort(nums);
        int len = nums.length, max = (1 << len);
        int res = 0;
        for (int i = 1; i < max; ++i) {
            int left = 0;
            boolean isValid = true;
            for (int j = 0; j < len; ++j) {
                if (isUsed(i, j)) {
                    while (left < j && nums[j] - nums[left] >= k) {
                        if (nums[j] - nums[left] == k && isUsed(i, left)) {
                            isValid = false;
                        }
                        ++left;
                    }
                    if (!isValid) {
                        break;
                    }
                }
            }
            if (isValid) {
                ++res;
            }
        }
        return res;
    }

    private boolean isUsed(int key, int offset) {
        int mark = (key >> offset) & 1;
        return mark == 1;
    }
}

6321. Smallest Missing Non-negative Integer After Operations

给你一个下标从 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 。

测试样例

输入:nums = [1,-10,7,13,6,8], value = 5

输出:4

解释:

执行下述操作可以得到这一结果:

  • nums[1] 加上 value 两次,nums = [1,0,7,13,6,8]
  • nums[2] 减去 value 一次,nums = [1,0,2,13,6,8]
  • nums[3] 减去 value 两次,nums = [1,0,2,3,6,8]

nums 的 MEX 是 4 。可以证明 4 是可以取到的最大 MEX 。

解答:这道题目需要计算mod value之后,每一位最大可到达的数字。然后遍历数组之后,查找第一个无法达到的非负整数

class Solution {
    public int findSmallestInteger(int[] nums, int value) {
        int[] min = new int[value];
        for (int i = 0; i < nums.length; ++i) {
            int tmp = (nums[i] % value + value) % value;
            min[tmp] += 1;
        }
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < value; ++i) {
            res = Math.min(res, i + min[i] * value);
        }
        return res;
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *