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;
}
}