1. 程式人生 > >【LeetCode】分治法 divide and conquer (共17題)

【LeetCode】分治法 divide and conquer (共17題)

【4】Median of Two Sorted Arrays 

【23】Merge k Sorted Lists 

【53】Maximum Subarray 

 

【169】Majority Element 

 

【215】Kth Largest Element in an Array (2018年12月11日,wiggle sort 專題,需要複習)

用 O(n) 的時間複雜度找到陣列中第 K 大的元素。重複元素也計入 K。

題解:本題可以用 heap 解答,時間複雜度是 O(nlogK)。其實還可以用 quick select 解答(也就是快排的partition(2-way partition)),平均複雜度是 O(n),最壞是 O(n^2)。為了搞平均,一開始要把陣列 random_shuffle 一下,儘可能避免 worst case。 

 1 class Solution {
 2 public:
 3     int findKthLargest(vector<int>& nums, int k) {
 4         random_shuffle(nums.begin(), nums.end());
5 const int n = nums.size(); 6 int start(0), end(n-1), index(n-k); 7 while (start < end) { 8 int idx = partition(nums, start, end); 9 if (idx < index) { 10 start = idx + 1; 11 } else if (idx > index) { 12
end = idx - 1; 13 } else { 14 return nums[idx]; 15 } 16 } 17 return nums[start]; 18 } 19 int partition(vector<int>& nums, int start, int end) { 20 int pivot = start; 21 while (start < end) { 22 while (nums[start] <= nums[pivot]) { 23 start++; 24 } 25 while (nums[end] > nums[pivot]) { 26 end--; 27 } 28 if (start > end) {break;} 29 swap(nums[start], nums[end]); 30 } 31 swap(nums[end], nums[pivot]); 32 return end; 33 } 34 35 };
View Code

 

【218】The Skyline Problem 

【240】Search a 2D Matrix II 

【241】Different Ways to Add Parentheses (2018年11月15日,演算法群)

給了一個字串算式,裡面含有 “+”,“-”,“*” 這三種運算子,可以在算式的任何一個地方加括號,整個算式能加的括號數不限。問這個算式所有可能的答案。

Example 1:
Input: "2-1-1"
Output: [0, 2]
Explanation: 
((2-1)-1) = 0 
(2-(1-1)) = 2

Example 2:
Input: "2*3-4*5"
Output: [-34, -14, -10, -10, 10]
Explanation: 
(2*(3-(4*5))) = -34 
((2*3)-(4*5)) = -14 
((2*(3-4))*5) = -10 
(2*((3-4)*5)) = -10 
(((2*3)-4)*5) = 10

 題解:我們可以在任意地方加括號,每個運算子的兩邊都可以加個括號看成是一個子問題,先把子問題的所有解求出來,然後把兩個子問題的解集合做笛卡爾積,形成大問題的解集合。

審題很重要,我一度以為如果運算子是 ‘-’ 的話,那麼後面的算式的 加號要變成減號,減號要變成加號,這個題意裡面是沒有的。

 1 class Solution {
 2 public:
 3     vector<int> diffWaysToCompute(string input) {
 4         return calPart(input);
 5     }
 6     vector<int> calPart(string s) {
 7         const int n = s.size();
 8         if (record.find(s) != record.end()) {return record[s];}
 9         //純數字的情況
10         if (s.find("+") == string::npos && s.find("-") == string::npos && s.find("*") == string::npos) {
11             vector<int> ret{stoi(s)};
12             return ret;
13         }
14         //含有運算子的情況
15         vector<int> res;
16         for (int i = 0; i < n; ++i) {
17             if (!isdigit(s[i])) {
18                 string front = s.substr(0, i), back = s.substr(i+1);
19                 vector<int> resFront = calPart(front), resBack = calPart(back);
20                 for (auto f : resFront) {
21                     for (auto b : resBack) {
22                         int tempres = 0;
23                         if (s[i] == '+') {
24                             tempres = f + b;
25                         } else if (s[i] == '-') {
26                             tempres = f - b;
27                         } else if (s[i] == '*') {
28                             tempres = f * b;
29                         }
30                         res.push_back(tempres);
31                     }
32                 }
33             }
34         }
35         //sort(res.begin(), res.end());
36         record[s] = res;
37         return res;
38     }
39     unordered_map<string, vector<int>> record;
40 };
View Code

 

【282】Expression Add Operators 

【312】Burst Balloons 

【315】Count of Smaller Numbers After Self 

【327】Count of Range Sum 

【426】Convert Binary Search Tree to Sorted Doubly Linked List 

【493】Reverse Pairs 

【514】Freedom Trail 

【903】Valid Permutations for DI Sequence 

【932】Beautiful Array