6362. 合并两个二维数组 - 求和法
将两个数组合并,第一个数相同的话,第二个参数相加
按 第一个元素从小到大 合并成 一个数组
map
class Solution {
public int[][] mergeArrays(int[][] nums1, int[][] nums2) {
HashMap<Integer, Integer> mp = new HashMap<>();
for (var x : nums1) {
mp.put(x[0], mp.getOrDefault(x[0], 0) + x[1]);
}
for (var x : nums2) {
mp.put(x[0], mp.getOrDefault(x[0], 0) + x[1]);
}
ArrayList<int[]> al = new ArrayList<>();
Set<Integer> ks = mp.keySet();
for (var x : ks) {
al.add(new int[]{x, mp.get(x)});
}
al.sort((a, b) -> (a[0] - b[0]));
int n = al.size();
int[][] ans = new int[n][2];
for (int i = 0; i < n; i++) {
ans[i][0] = al.get(i)[0];
ans[i][1] = al.get(i)[1];
}
return ans;
}
}
归并
class Solution {
public int[][] mergeArrays(int[][] a, int[][] b) {
ArrayList<int[]> al = new ArrayList<>();
int n = a.length, m = b.length, i = 0, j = 0;
while ( true ) {
if (i == n) {
while (j < m) {
al.add(new int[]{b[j][0], b[j][1]});
j++;
}
break;
}
if (j == m) {
while (i < n) {
al.add(new int[]{a[i][0], a[i][1]});
i++;
}
break;
}
if (a[i][0] < b[j][0]) {
al.add(new int[]{a[i][0], a[i][1]});
i++;
}
else if (a[i][0] == b[j][0]) {
al.add(new int[]{b[j][0], b[j][1] + a[i][1]});
i++;
j++;
}
else {
al.add(new int[]{b[j][0], b[j][1]});
j++;
}
}
int[][] ans = new int[al.size()][2];
for (i = 0; i < al.size(); i++) {
var pr = al.get(i);
ans[i][0] = pr[0];
ans[i][1] = pr[1];
}
return ans;
}
}
6365. 将整数减少到零需要的最少操作数
贪心
class Solution {
private int[] p2 = new int[20];
public int minOperations(int n) {
int ans = 0;
p2[0] = 1;
int x = 1;
for (int i = 1; i < 20; i++) {
x *= 2;
p2[i] = x;
}
while (n != 0) {
int t = 0;
x = Math.abs(n);
for (int i = 0; i < 17; i++) {
if (p2[i] <= x && p2[i + 1] >= x) {
t = i;
break;
}
}
// System.out.println(t);
int a = p2[t];
int b = p2[t + 1];
// System.out.println(a + " " + b);
a = x - a;
b = b - x;
if (Math.abs(a) <= Math.abs(b)) {
if (n > 0) n -= p2[t];
else n += p2[t];
ans++;
} else {
if (n > 0) n -= p2[t + 1];
else n += p2[t + 1];
ans++;
}
// System.out.println(n);
if (n == 0) break;
}
return ans;
}
}
二进制+dfs
class Solution {
/*
将 n 变成 0,每次 + / - 去 2 的次幂,即每次改变一个二进制位
如果当前位置是 1,加上 / 减去 1 都可以消去
如果先操作高位的 1,在你操作后面 低位的 1 时,可能还是会改变前面的状态
为了保持状态,(无后效性),我们每次都操作最低位的 1,
得到最低位的 1 ===> lowbit = x & (~x + 1)
判断某个数是否是 二的幂次:x & (x - 1) == 0
记忆化搜索,判断 +1 和 -1 哪个次数少
*/
public int minOperations(int n) {
return dfs(n);
}
// 记忆化
private int dfs(int x) {
if ((x & (x - 1)) == 0) return 1; // x 是 二的次幂,操作一次即可
int lb = low_bit(x);
return 1 + Math.min(dfs(x + lb), dfs(x - lb));
}
// 得到最低位的 1
private int low_bit(int x) {return x & (~x + 1);}
}