[Leetcode Weekly Contest]200

链接:LeetCode

[Leetcode]5475. 统计好三元组

给你一个整数数组 arr ,以及 a、b 、c 三个整数。请你统计其中好三元组的数量。
如果三元组 ((arr[i], arr[j], arr[k])) 满足下列全部条件,则认为它是一个 好三元组 。

  • 0 <= i < j < k < arr.length
  • (|arr[i] - arr[j]| <= a)
  • (|arr[j] - arr[k]| <= b)
  • (|arr[i] - arr[k]| <= c)

其中 (|x|) 表示 x 的绝对值。
返回 好三元组的数量 。

根据题意暴力即可。

class Solution {
public:
    int abs(int x){
        return x>0?x:-x;
    }

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

[Leetcode]5476. 找出数组游戏的赢家

给你一个由 不同 整数组成的整数数组 arr 和一个整数 k 。
每回合游戏都在数组的前两个元素(即 arr[0] 和 arr[1] )之间进行。比较 arr[0] 与 arr[1] 的大小,较大的整数将会取得这一回合的胜利并保留在位置 0 ,较小的整数移至数组的末尾。当一个整数赢得 k 个连续回合时,游戏结束,该整数就是比赛的 赢家 。
返回赢得比赛的整数。
题目数据 保证 游戏存在赢家。

遍历数组维护一个最大值,并且统计他几次会被下一个最大值替换掉。也就相当于题目中的比较操作。如果有其中一个最大值替换次数 >= k 那么直接返回这个最大值。若遍历完成后无返回,由于数据保证游戏存在赢家,此时只要返回整个数组最大值就好。

# include <cmath>
class Solution {
public:
    int getWinner(vector<int>& arr, int k) {
        int n = arr.size();
        int pre = arr[0],cur = 0;
        int max_num;
        for(int i=1;i<n;++i){
            max_num = max(pre,arr[i]);
            if(max_num==pre){
                cur ++ ;
            }
            else{
                cur = 1;
                pre = max_num;
            }
            if(cur>=k){
                return max_num;
            }
        }
        return max_num;
    }
};

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

给你一个 n x n 的二进制网格 grid,每一次操作中,你可以选择网格的 相邻两行 进行交换。
一个符合要求的网格需要满足主对角线以上的格子全部都是 0 。
请你返回使网格满足要求的最少操作次数,如果无法使网格符合要求,请你返回 -1 。
主对角线指的是从 (1, 1) 到 (n, n) 的这些格子。

要想实现对角线以上格子全是0,那么我们只需要记录,每一行从后往前遍历,连续0的个数。根据贪心思想,从第一行开始,如果该行的后缀0满足条件,那么直接跳过进入下一行(因为需要的后缀0个数是从大到小的顺序,所以不必担心前面的会抢后面的);如果该行后缀0个数不满足条件,那么就往下遍历找到最先(贪心,这是最小次数)满足条件的行,一行一行换上来,记录交换的次数。如果找不到满足条件的后缀0,那么就返回-1.

class Solution {
public:
    int minSwaps(vector<vector<int>>& grid) {
        vector<int> inds;
        int n = grid.size();
        for(int i=0;i<n;++i){
            int cur = 0;
            for(int j=n-1;j>=0;--j){
                if(grid[i][j]==0) cur ++;
                else break;
            }
            inds.push_back(cur);
        }
        int res = 0;
        for(int i=0;i<n-1;++i){
            int wants = n-1-i,j;
            bool flag = false;
            for (j=0;j<inds.size();++j){
                if(inds[j]>=wants){
                    flag = true;
                    res += j;
                    break;
                }
            }
            if(!flag) return -1;
            inds.erase(inds.begin()+j);
        }
        return res;

    }
};

[Leetcode]5478. 最大得分

你有两个 有序 且数组内元素互不相同的数组 nums1 和 nums2 。
一条 合法路径 定义如下:
选择数组 nums1 或者 nums2 开始遍历(从下标 0 处开始)。
从左到右遍历当前数组。
如果你遇到了 nums1 和 nums2 中都存在的值,那么你可以切换路径到另一个数组对应数字处继续遍历(但在合法路径中重复数字只会被统计一次)。
得分定义为合法路径中不同数字的和。
请你返回所有可能合法路径中的最大得分。
由于答案可能很大,请你将它对 10^9 + 7 取余后返回。

双指针遍历即可。

class Solution {
    typedef long long ll;
    const int P=1000000007;

public:
    int maxSum(vector<int>& nums1, vector<int>& nums2) {
        int i=0,j=0;
        ll sum1=0,sum2=0,res = 0;
        while(i<nums1.size() && j<nums2.size()){
            if(nums1[i]<nums2[j]){
                sum1 += nums1[i];
                i++;
            }
            else if(nums1[i]> nums2[j]){
                sum2 += nums2[j];
                j++;
            }
            else{
                res += max(sum1,sum2)+nums1[i];
                sum1 = sum2 =0;
                i++;
                j++;
            }
        }
        for(;i<nums1.size();++i){
            sum1 += nums1[i];
        }
        for(;j<nums2.size();++j){
            sum2 += nums2[j];
        }
        res += max(sum1,sum2);
        return res%P;

    }
};

参考:
Leetcode

原文地址:https://www.cnblogs.com/hellojamest/p/13419102.html