LeetCode 第 216 場周賽 題解
掃描二維碼關注公眾號,為作者三連,你們的鼓勵就是我們最大的動力!
題目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)。