[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