LeetCode 第 35 場雙週賽(216/2839,前7.61%)

1. 比賽結果

作出來3題。繼續加油!數組

全國排名: 216 / 2839,7.61%;全球排名: 585 / 8750,6.70%



學習

2. 題目

1. LeetCode 5503. 全部奇數長度子數組的和 easy

題目連接spa

給你一個正整數數組 arr ,請你計算全部可能的奇數長度子數組的和。.net

子數組 定義爲原數組中的一個連續子序列code

請你返回 arr 中 全部奇數長度子數組的和 。blog

示例 1:
輸入:arr = [1,4,2,5,3]
輸出:58
解釋:全部奇數長度子數組和它們的和爲:
[1] = 1
[4] = 4
[2] = 2
[5] = 5
[3] = 3
[1,4,2] = 7
[4,2,5] = 11
[2,5,3] = 10
[1,4,2,5,3] = 15
咱們將全部值求和獲得 
1 + 4 + 2 + 5 + 3 + 7 + 11 + 10 + 15 = 58

示例 2:
輸入:arr = [1,2]
輸出:3
解釋:總共只有 2 個長度爲奇數的子數組,
[1][2]。它們的和爲 3 。

示例 3:
輸入:arr = [10,11,12]
輸出:66
 
提示:
1 <= arr.length <= 100
1 <= arr[i] <= 1000

解題:排序

  • 先計算前綴和,再枚舉子數組開始位置和奇數長度
  • 時間複雜度 O ( n 2 ) O(n^2) O(n2)
class Solution { 
public:
    int sumOddLengthSubarrays(vector<int>& arr) { 
        int n = arr.size(), sum = 0;
        for(int i = 1; i < n; ++i) 
        { 
            arr[i] = arr[i-1] + arr[i];
        }
        
        for(int i = 0; i < n; ++i)
        { 
            for(int len = 1; len <= n; len+=2)
            { 
                int j = i+len-1;
                if(j >= n)
                    break;
                sum += arr[j]- (i > 0 ? arr[i-1] : 0);
            }
        }
        return sum;
    }
};

4 ms 8 MB索引

  • 參考大佬的思路
  • 對每一個數字考慮先後的奇偶數字的長度有多少種,先後同奇同偶的方案數相乘
  • 時間複雜度 O ( n ) O(n) O(n)
class Solution { 
public:
    int sumOddLengthSubarrays(vector<int>& arr) { 
        int n = arr.size(), sum = 0;
        int L_odd, L_even, R_odd, R_even, L, R;
        for(int i = 0; i < n; ++i)
        { 
            //對每一個數字進行考察 1個數字
            //它的左邊右邊有的數字個數必須是同奇同偶
            //這樣子數組纔會是奇數個長度
            //有多少種組合
            L_odd = (i+1)/2;//奇數有這麼多種選擇
            L_even = i/2;
            R_odd = (n-i)/2;
            R_even = (n-i-1)/2;
            sum += (L_odd*R_odd + (L_even+1)*(R_even+1))*arr[i];
                                    // +1 爲先後偶數個數爲0的狀況
        }
        return sum;
    }
};

0 ms 8.1 MBleetcode

2. LeetCode 5505. 全部排列中的最大和 medium

題目連接get

有一個整數數組 nums ,和一個查詢數組 requests ,其中 requests[i] = [starti, endi] 。第 i 個查詢求 nums[starti] + nums[starti + 1] + ... + nums[endi - 1] + nums[endi] 的結果 ,starti 和 endi 數組索引都是 從 0 開始 的。

你能夠任意排列 nums 中的數字,請你返回全部查詢結果之和的最大值

因爲答案可能會很大,請你將它對 10^9 + 7 取餘 後返回。

示例 1:
輸入:nums = [1,2,3,4,5], requests = [[1,3],[0,1]]
輸出:19
解釋:一個可行的 nums 排列爲 [2,1,3,4,5],並有以下結果:
requests[0] -> nums[1] + nums[2] + nums[3] = 1 + 3 + 4 = 8
requests[1] -> nums[0] + nums[1] = 2 + 1 = 3
總和爲:8 + 3 = 11。
一個總和更大的排列爲 [3,5,4,2,1],並有以下結果:
requests[0] -> nums[1] + nums[2] + nums[3] = 5 + 4 + 2 = 11
requests[1] -> nums[0] + nums[1] = 3 + 5  = 8
總和爲: 11 + 8 = 19,這個方案是全部排列中查詢之和最大的結果。

示例 2:
輸入:nums = [1,2,3,4,5,6], requests = [[0,1]]
輸出:11
解釋:一個總和最大的排列爲 [6,5,4,3,2,1] ,查詢和爲 [11]。

示例 3:
輸入:nums = [1,2,3,4,5,10], requests = [[0,2],[1,3],[1,1]]
輸出:47
解釋:一個和最大的排列爲 [4,10,5,3,2,1] ,查詢結果分別爲 [19,18,10]。
 
提示:
n == nums.length
1 <= n <= 105
0 <= nums[i] <= 105
1 <= requests.length <= 105
requests[i].length == 2
0 <= starti <= endi < n

解題:

  • 計算頻數,頻數大的乘以大數,這樣總和才能最大
  • 頻數計算要採用差分方法,模擬會超時
    相似題目 LeetCode 1109. 航班預訂統計(差分思想)
  • 時間複雜度爲排序的複雜度 O ( n log ⁡ n ) O(n\log n) O(nlogn)
class Solution { 
public:
    int maxSumRangeQuery(vector<int>& nums, vector<vector<int>>& requests) { 
        int n = nums.size();
        vector<long long> f(n+1, 0);
        for(auto& re : requests)
        { 
            f[re[0]]++;
            f[re[1]+1]--;
        }
        for(int i = 1; i <= n; i++)
        { 
            f[i] += f[i-1];
        }
        sort(f.rbegin(), f.rend());
        sort(nums.rbegin(), nums.rend());
        long long sum = 0, mod = 1e9+7;
        for(int i = 0; i < n; i++)
        { 
            sum = (sum+f[i]*nums[i])%mod;
        }
        return sum;
    }
};

1240 ms 95.9 MB

3. LeetCode 5504. 使數組和能被 P 整除 medium

題目連接

給你一個正整數數組 nums,請你移除 最短 子數組(能夠爲 空),使得剩餘元素的 能被 p 整除
不容許整個數組都移除。

請你返回你須要移除的最短子數組,若是沒法知足題目要求,返回 -1 。

子數組 定義爲原數組中連續的一組元素。

示例 1:
輸入:nums = [3,1,4,2], p = 6
輸出:1
解釋:nums 中元素和爲 10,不能被 p 整除。
咱們能夠移除子數組 [4] ,剩餘元素的和爲 6 。

示例 2:
輸入:nums = [6,3,5,2], p = 9
輸出:2
解釋:咱們沒法移除任何一個元素使得和被 9 整除,
最優方案是移除子數組 [5,2] ,剩餘元素爲 [6,3],和爲 9 。

示例 3:
輸入:nums = [1,2,3], p = 3
輸出:0
解釋:和剛好爲 6 ,已經能被 3 整除了。
因此咱們不須要移除任何元素。

示例  4:
輸入:nums = [1,2,3], p = 7
輸出:-1
解釋:沒有任何方案使得移除子數組後剩餘元素的和被 7 整除。

示例 5:
輸入:nums = [1000000000,1000000000,1000000000], p = 3
輸出:0
 
提示:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
1 <= p <= 10^9

解題:

class Solution { 
public:
    int minSubarray(vector<int>& nums, int p) { 
        long long mod = 0, sum = 0;
        for(int i = 0; i < nums.size(); i++)
        { 
            mod = (mod + nums[i])%p;
            sum += nums[i];
        }
        if(mod == 0)//餘數爲0,不須要操做
            return 0;
        if(sum < p)//和小於p, 作不到
            return -1;
        int s = 0, minlen = INT_MAX;
        // s 是求模後的和
        unordered_map<int, int> m;//記錄和求模後的數,及其位置
        m[0] = -1;//初始條件,0 在 -1 位置
        for(int i = 0; i < nums.size(); i++)
        { 
            s = (s + nums[i])%p;
            int target = (s-mod+p)%p;
            //檢查跟 s 相差 須要的餘數mod 的餘數存在嗎
            if(m.find(target) != m.end())
            { 
                minlen = min(minlen, i-m[target]);
            }
            m[s] = i;//更新位置
        }
        return minlen >= nums.size() ? -1 : minlen;
    }
};

420 ms 65.4 MB

4. LeetCode 5506. 奇怪的打印機 II hard

題目連接

給你一個奇怪的打印機,它有以下兩個特殊的打印規則:

  • 每一次操做時,打印機會用同一種顏色打印一個矩形的形狀,每次打印會覆蓋矩形對應格子裏本來的顏色。
  • 一旦矩形根據上面的規則使用了一種顏色,那麼 相同的顏色不能再被使用

給你一個初始沒有顏色m x n 的矩形 targetGrid ,其中 targetGrid[row][col] 是位置 (row, col) 的顏色。

若是你能按照上述規則打印出矩形 targetGrid ,請你返回 true ,不然返回 false 。

示例 1:

輸入:targetGrid = [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]]
輸出:true

示例 2:

輸入:targetGrid = [[1,1,1,1],[1,1,3,3],[1,1,3,4],[5,5,1,4]]
輸出:true

示例 3:
輸入:targetGrid = [[1,2,1],[2,1,2],[1,2,1]]
輸出:false
解釋:沒有辦法獲得 targetGrid ,由於每一輪操做使用的顏色互不相同。

示例 4:
輸入:targetGrid = [[1,1,1],[3,1,3]]
輸出:false
 
提示:
m == targetGrid.length
n == targetGrid[i].length
1 <= m, n <= 60
1 <= targetGrid[row][col] <= 60

解題:

待學習。


個人CSDN博客地址 https://michael.blog.csdn.net/

長按或掃碼關注個人公衆號(Michael阿明),一塊兒加油、一塊兒學習進步!
Michael阿明

相關文章
相關標籤/搜索