1. 程式人生 > 實用技巧 >LeetCode 第 216 場周賽 題解

LeetCode 第 216 場周賽 題解

第 216 場周賽

點選這裡看配圖版,為作者打Call !!!

掃描二維碼關注公眾號,為作者三連,你們的鼓勵就是我們最大的動力!

題目1:5605. 檢查兩個字串陣列是否相等

思路:模擬

將兩個陣列的字串分別按序拼接,然後比較兩字串是否相等即可。

程式碼:

1 class Solution {
2 public:
3    bool arrayStringsAreEqual(vector<string>& word1, vector<string>& word2) {
4        string a = "", b = "";
5        for
(auto w : word1) a += w; 6 for(auto w : word2) b += w; 7 return a == b; 8 } 9 };

複雜度分析:

時間複雜度為​O(n),空間複雜度為O(n)

題目2:5606. 具有給定數值的最小字串

思路:模擬

題目說明了給定 一定能構造出字串,所以先將所有 位都初始化為字元,一定是目前數值最小的字串,維護一個變數 記錄當前字串數值,修改字串從末尾開始增加(為了保證最小字典序),若最後一位已經修改到字元 ,則倒數第二位開始增加,所以維護一個 變數記錄當前需要修改的位置。直到 時結束。

程式碼:

 1 class Solution {
 2 public:
 3    string getSmallestString(int n, int k) {
 4        string res = "";
 5        int cnt = 0;
 6        for(int i = 0; i < n; i++) {
 7            res += "a";
 8            cnt++;
 9       }
10        int pos = 1;
11        while(k > cnt) {
12            if
(res[n - pos] == 'z') { 13 pos++; 14 } 15 res[n - pos]++; 16 k--; 17 } 18 return res; 19 } 20 };

複雜度分析:

時間複雜度為​O(n),空間複雜度為O(n)

題目3:5607. 生成平衡陣列的方案數

思路:字首和

由於刪除一個數後,這個數後面所有數都向前挪動一位,所以原本奇數位的數變成了偶數位,偶數位的數變成了奇數位。那麼對於一個刪除的下標位置,刪除該元素後,後面所有奇數下標元素的和其實就是移除之前,後面所有偶數下標元素的和。所以提前維護兩個字首和,分別記錄奇數下標元素和偶數下標元素之和即可。

程式碼:

 1 class Solution {
 2 public:
 3    int waysToMakeFair(vector<int>& nums) {
 4        int n = nums.size();
 5        vector<int> odd(n + 1, 0);
 6        vector<int> even(n + 1, 0);
 7        for(int i = 1; i <= n; i++) {
 8            if(i % 2 == 1) {
 9                odd[i] = odd[i - 1];
10                even[i] = even[i - 1] + nums[i - 1];
11           } else {
12                odd[i] = odd[i - 1] + nums[i - 1];
13                even[i] = even[i - 1];
14           }
15       }
16        
17        int cnt = 0;
18        for(int i = 0; i < n; i++) {
19            int o = odd[i] - odd[0] + even[n] - even[i + 1]; // 奇數下標元素之和
20            int e = even[i] - even[0] + odd[n] - odd[i + 1]; // 偶數下標元素之和
21            if(o == e) {
22                cnt++;
23           }
24       }
25        return cnt;
26   }
27 };

複雜度分析:

時間複雜度為​O(n),空間複雜度為O(n)

題目4:5608. 完成所有任務的最少初始能量

思路:貪心

題目要求最少初始能量,我們反向考慮這個問題,假設初始能量 。現在我們考慮要做的第一個任務,為了開始執行這個任務,我們需要“補”差價,也就是補上 值的能量。最終完成所有任務需要補的能量之和就是題目要求的最少初始能量。在完成這個任務後,我們還剩餘能量 ,此時我們需要繼續去完成其他任務。當完成最後一個任務後,剩餘的能量就沒用了。所以,我們希望儘可能將剩餘能量 較大的任務放在前面做,這樣在完成一個任務後,我們為了完成下一個任務需要補的“差價”就少,同樣地,我們把剩餘能量較小的任務放在後面做,這樣完成最後一個任務後,我們就不會“心疼”扔掉的能量了。

當兩個任務具有相同的剩餘能量 時,我們優先選擇做 較大的任務,這是因為,完成兩個任務後,剩餘能量相等,假設先做了任務1,那麼下面要做任務2,需要補差價 , 而若是先做任務2,再做任務1時需要補的差價就是 ,由於, 故先做 較大的任務,需要補的差價就少了。

程式碼:

 1 class Solution {
 2 public:
 3    struct task{
 4        int x, y;
 5        task(int x, int y):x(x), y(y){}
 6        bool operator<(const task& a) const {
 7            if(a.y - a.x == y - x) {
 8                // 剩餘能量相同,先做y較大的任務
 9                return y < a.y;
10           }
11            // 先做剩餘能量大的任務
12            return y - x < a.y - a.x;
13       }
14   };
15    
16    int minimumEffort(vector<vector<int>>& tasks) {
17        priority_queue<task> q;
18        for(auto t : tasks) {   // 放入優先佇列
19            task tmp(t[0], t[1]);
20            q.push(tmp);
21       }
22        // res 記錄補差價總量,也即最終要求結果
23        // pos 記錄當前剩餘能量
24        int res = 0, pos = 0;
25        while(!q.empty())
26       {
27            task tmp = q.top();
28            if(pos >= tmp.y) {// 不用補差價
29                pos -= tmp.x;
30           } else {
31                res += tmp.y - pos;
32                pos = tmp.y - tmp.x;
33           }
34            q.pop();
35       }
36        return res;
37   }
38 };

複雜度分析:

時間複雜度為​O(nlgn),空間複雜度為O(n)

掃描二維碼關注公眾號,為作者三連,你們的鼓勵就是我們最大的動力!