LeetCode 第 44 场双周赛
第一题: 5645. 找到最高海拔
暴力题
从 0 开始然后逐渐加入 gain 数组更新和找到最大值(最高海拔)
AC Code
class Solution {
public int largestAltitude(int[] g) {
int ans = 0;
int s = 0, len = g.length;
for(int i = 0; i < len; i++) {
ans = Math.max(ans, s);
s += g[i];
}
ans = Math.max(ans, s);
return ans;
}
}
第二题: 5646. 需要教语言的最少人数
暴力模拟
先找出每种语言哪些人已经学会了,再找出为了维持朋友关系,每种语言分别需要教哪些人(如果已经学会了就不需要再教了),取各个语言需要教的人数的最小值。
注意: 好友关系没有传递性
AC Code
class Solution {
public int minimumTeachings(int n, int[][] l, int[][] f) {
// 1 -> 2 3
// 2 -> 1 3
// 3 -> 2 4
Set<Integer>[] set = new HashSet[n + 1];
// 记录学习语言的用户
Set<Integer>[] user = new HashSet[n + 1];
// 初始化
for(int i = 0; i < n + 1; i++) {
set[i] = new HashSet<>();
user[i] = new HashSet<>();
}
// 初始化语言下都有哪些人
for(int i = 0; i < l.length; i++) {
int size = l[i].length;
for(int j = 0; j < size; j++) set[l[i][j]].add((i + 1));
}
int len = f.length;
// 查询朋友关系
for(int i = 0; i < len; i++) {
boolean b = false;
// 遍历 n 种语言
for(int j = 1; j < n + 1; j++) {
// 这两个朋友都学了这种语言
if(set[j].contains(f[i][0]) && set[j].contains(f[i][1])) {
b = true; break;
}
}
if(b) continue ;
// 学习语言
for(int j = 1; j < n + 1; j++) {
if(!set[j].contains(f[i][0])) user[j].add(f[i][0]);
if(!set[j].contains(f[i][1])) user[j].add(f[i][1]);
}
}
int ans = Integer.MAX_VALUE;
for(int i = 1; i < n + 1; i++) {
ans = Math.min(ans, user[i].size());
}
return ans;
}
}
第三题: 5647. 解码异或后的排列
当时想到用这个特点 a ^ a = 0, 0 ^ b = b 去解决
但是方向还是歪了
解决思路:
- 通过给出的 encode 数组所有奇数位上的异或结果 s , 可以得到除开头以外的 n -1 个数的异或结果
- 然后 s 再与 1 到 n 的数进行异或,将多余出来的都抵消掉,剩下的就是 perm 原数组开头的那个
- 将开头找出来了,剩下的就迎刃而解了
encoded = [6,5,4,6]
假设 perm[]{a1, a2, a3, a4, a5}
a1 ^ a2 == 6
a2 ^ a3 == 5
a3 ^ a4 == 4
a4 ^ a5 == 6
我们需要的时候 a2 ^ a3 ^ a4 ^ a5 -> 求出 a1 之后就好解了
a2 ^ a3 ^ a4 ^ a5 == encoded[1] ^ encoded[3]
AC Code
class Solution {
public int[] decode(int[] e) {
int s = 0;
int len = e.length;
// e 数组奇数位的异或起来 等价于 从 perm 数组index = 1 开始异或的结果
for(int i = 1; i < len; i += 2) s ^= e[i];
// 因为 perm 数组是从 1 到 n 的
for(int i = 1; i <= len + 1; i++) s ^= i;
// 此时 sum == perm[0]
// 保存结果
int[] ans = new int[len + 1];
int idx = 0;
ans[idx++] = s;
for(int i = 1; i <= len; i++) {
ans[idx] = ans[idx - 1] ^ e[i - 1];
idx++;
}
return ans;
}
}
第四题: 5648. 生成乘积数组的方案数
待补
唯一分解+组合数
AC Code