1. 程式人生 > 實用技巧 >LeetCode 200場周賽

LeetCode 200場周賽

思路:

  • 暴力。
class Solution {
public:
    int countGoodTriplets(vector<int>& arr, int a, int b, int c) {
        int cnt = 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 ( (-a <= arr[i] - arr[j]) && (a >= arr[i] - arr[j])) 
                        
                    if ( (-b <= arr[j] - arr[k]) && (b >= arr[j] - arr[k])) 
                        
                    if ( (-c <= arr[i] - arr[k]) && (c >= arr[i] - arr[k])) 
                        cnt++;
                }
            }
        }
        return cnt;
    }
};

思路:

  • 直接暴力模擬會超時。
  • 這裡使用指標快速遍歷一遍陣列就行。

class Solution {
public:
       
    int getWinner(vector<int>& arr, int k) {
        
        int win = 0;
        
        int index = -1;
        int temp;
        int cnt = 0;
        if (k == 1){
             if (arr[0] - arr[1] > 0) {
                 return arr[0];
             } else {
                 return arr[1];
             }
            
        }
        
        // int M = arr[0];
        // for (int i = 1; i < arr.size(); i++) {
        //     if (M < arr[i])
        //         M = arr[i];
        // }
        while (cnt <= arr.size() - 1){
            cnt++;
            
            if (arr[0] - arr[cnt] > 0) {
                
                win++;         
            } else {
                temp = arr[0];
                arr[0] = arr[cnt];
                arr[cnt] = temp;
                win = 1;
            }
            if (win == k){
                return arr[0];
            }
            
            
        }
        
        return arr[0];
    }
    
};

1536.排布二進位制網格的最少交換次數

思路:

  • 由於只能是行的交換所以,對於每一行的0和1的位置並不發生改變。
  • 第一行的字尾0只能是在第2個
  • 第二行的字尾0只能是在第3個
  • ...
  • 尋找最符合的字尾0的位置 當前行符合就跳過 不符合就去找最近符合的 並記錄交換次數
  • 找不到則直接返回-1
class Solution {
public:
    int minSwaps(vector<vector<int>>& grid) {
        int n = grid.size(); //網格規模
        vector<int> a; //記錄每一行字尾0個數的陣列
        for(int i = 0; i < n; i++)
        {
            int count = 0;
            for(int j = n - 1; j >= 0; j--)
            {
                if(grid[i][j] == 0) count++; //數每一行的字尾0
                else break;
            }
            a.push_back(count); 
        }
        int count = 0; //交換次數
        for(int i = 0; i < n - 1; i++)
        {
            if(a[i] >= n - i - 1) continue;//滿足條件,該行直接跳過
            else{//不滿足條件
                int j = i; //用新引數遍歷找滿足條件的字尾0
                for(; j < n; j++)
                {
                    if(a[j] >= n - i - 1) break;
                }
                if(j == n) return -1; //找不到,直接返回-1
                for(; j > i; j--) //找到了最先滿足條件的字尾0個數 
                {
                    swap(a[j], a[j - 1]); //每一行交換上去
                    count++; //記錄交換次數
                }
            }
        }
        return count;
    }
};

思路:

相交點可以將2個數組都分成(K + 1)段,統計每段的和,並取較大值計入結果,可以用雙指標快速實現。

int maxSum(vector<int>& nums1, vector<int>& nums2) {
        long sum1 = 0, sum2 = 0;
        long res = 0;
        int i = 0, j = 0;
        while(i < nums1.size() && j < nums2.size()){
            if(nums1[i] == nums2[j]){
                res += (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++;
        }
        res += max(sum1, sum2);
        return res % ((int)pow(10, 9) + 7 );
}