1. 程式人生 > 實用技巧 >[Leetcode Weekly Contest]200

[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