LeetCode 第 44 场双周赛 ( 拉跨操作 rank 990 / 1826 )

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 去解决

但是方向还是歪了

解决思路:

  1. 通过给出的 encode 数组所有奇数位上的异或结果 s , 可以得到除开头以外的 n -1 个数的异或结果
  2. 然后 s 再与 1 到 n 的数进行异或,将多余出来的都抵消掉,剩下的就是 perm 原数组开头的那个
  3. 将开头找出来了,剩下的就迎刃而解了

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值