[LeetCode] 周赛200

LeetCode 周赛200


5475. 统计好三元组

难度: Easy

题目描述:

链接:5475. 统计好三元组

解题思路:

暴力三重循环模拟

class Solution {
public:
    int countGoodTriplets(vector<int>& arr, int a, int b, int c) {
        int ans = 0;
        
        for(int i = 0; i < arr.size(); i++){
            for(int j = i + 1; j < arr.size(); j++){
                for(int k = j + 1;k < arr.size(); k++){
                    if(abs(arr[i] - arr[j]) <= a && abs(arr[j] - arr[k]) <= b && abs(arr[i] - arr[k]) <= c){
                        ans++;
                    }
                    
    }
        }
        }
        return ans;

    }
};

5476. 找出数组游戏的赢家

难度:Medium

题目描述:

链接:5476. 找出数组游戏的赢家

解题思路:

首先模拟的过程中,不需要对将前两个中较小的结点移到末尾。
采用两个下标指针,nowWinner指向当前的最大值,i指向当前挑战的结点。

  • 当当前最大的结点nowWinner > i ,则计数器nowCount+1
  • 否则,挑战结点i变为nowWinner,计数器nowCount 置 1
  • 计数器达到k时,返回结果
class Solution {
public:
    int getWinner(vector<int>& arr, int k) {
        
        int nowWinner = 0;
        int nowCount = 0;
        
        for(int i = 1; i < arr.size(); i++){
            
            if(arr[nowWinner] < arr[i]){
                nowWinner = i;
                nowCount = 1;
            }else{
                nowCount++;
            }
            
            if(nowCount >= k){
                break;
            }
        }
        
        return arr[nowWinner];
    }
};

5478. 最大得分

难度:Hard

题目描述:

题目链接:
5478. 最大得分

解题思路:

假设有K个值相同的结点,则把整2个数组分成了k+1段,

  • 每次统计两个数组各段中的sum1,sum2,
  • 然后在相同的节点处进行统计,ans += max(sum1, sum2) + nums1[i]
  • 注意要处理较长的数组,剩下的部分,额外加到ans中,ans += max(sum1, sum2)
class Solution {
public:
    int maxSum(vector<int>& nums1, vector<int>& nums2) {
        int i = 0,j = 0;
        long sum1 = 0, sum2 = 0;
        long ans = 0;

        while(i < nums1.size() && j < nums2.size()){
            if(nums1[i] == nums2[j]){   // 走到公共结点时统计结点的最大值
                ans += (max(sum1, sum2) + nums1[i]);
                sum1 = 0;
                sum2 = 0;
                i++;
                j++;
            }else if(nums1[i] < nums2[j]){
                sum1 += nums1[i];
                i++;
            }else{
                sum2 += nums2[j];
                j++;
            }
        }

        // 处理长度较长的数组的剩余部分
        while(i < nums1.size()){
            sum1 += nums1[i];
            i++;
        }
        while(j < nums2.size()){
            sum2 += nums2[j];
            j++;
        }

        ans += max(sum1, sum2);
        return ans % ((int)pow(10, 9) + 7);
    }
};

5477. 排布二进制网格的最少交换次数

难度: Medium

题目描述:

5477. 排布二进制网格的最少交换次数

解题思路:

采用贪心策略。满足条件的行后缀0的个数必须大于n-i-1个。

  1. 遍历每一行,统计每一行的后缀0的个数,存入count0的数组中
  2. 从第一行向下判断每一行的count0是否符合条件,符合条件则判断下一行
  3. 如果不符合,向下寻找第一个符合条件的行j,然后一次交换j和j-1,直到i处
  4. 如果找不到符合的行,则返回-1
class Solution {
public:
    int minSwaps(vector<vector<int>>& grid) {
        int n = grid.size();
        vector<int> count0; // 用来统计每一行后缀0的个数

        // 每一行从后向前,统计后缀中0的个数
        for(int i = 0; i < n; i++){
            int temp = 0;
            for(int j = n-1; j >= 0; j--){
                if(grid[i][j] == 0){
                    temp++;
                }else{
                    break;
                }
            }
            count0.push_back(temp);
        }

        int count_change = 0;   // 记录交换的次数

        // 一次判断每一行是否满足条件
        // 不满足条件的行一次向上交换
        for(int i = 0; i < n; i++){
            if(count0[i] >= n - i - 1){     // 当前行符合后缀0的个数,直接判断下一行
                continue;
            }else{
                int j = i;
                for(; j < n; j++){          // 寻找下面的行中,满足条件的下标j
                    if(count0[j] >= n - i - 1){
                        break;
                    }
                }

                if(j == n){                 // 没有符合条件的行
                    return -1;
                }else{
                    for(; j > i; j--){      // 依次向上交换
                        swap(count0[j-1], count0[j]);
                        count_change++;
                    }
                }
            }
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值