leedcode第15題三數之和詳解
阿新 • • 發佈:2018-12-11
vector<vector<int>> leedcode15::easy_threeSum(vector<int>& nums) { /** * 巧妙解法:其中有一些剪枝優化的思想 * 1、先對給定的陣列進行從小到大排序 * 如: 1, 2, -1, -3, 0, 3 * 排序:-3, -1, 0, 1, 2, 3 * 2、從排序後陣列中第一個元素開始固定, *如固定-3,然後設定一個指標p1指向-1,設定另一個指標p2指向3。 * 1)若*p1 + *p2 = 3,則返回這三個數值,然後兩個指標同時移動, *若只移動一個指標,結果必定是重複的三個數值,或者不相等。 * 2)若*p1 + *p2 < 3, 則將p1指標向右移動,若*p1 + *p2 > 3則反之。 * 3)注意:若指標移動後的值與沒有移動的值相同,則要跳過。 * 依次固定直到固定的元素大於0 */ //0 0 0 0 0 0 0 0 0 //0 1 2 3 4 5 6 7 8 //-5 -5 -4 -4 -4 -2 -2 -2 0 0 0 1 1 3 4 4 //vector<int> vec_result; vector<vector<int>> result; //設定一個容器的容器用來盛放結果 if (nums.size() < 3) return result; //非常重要的程式碼,邊界條件傳入陣列小於3則直接返回 sort(nums.begin(), nums.end()); //對傳入的容器內的元素進行排序。 //for(int i = 0; i < nums.size(); i++) int i = 0; //固定第一個元素 while(i != nums.size() - 2) //固定第一個元素,開始總迴圈,直到固定到倒數第三個元素 { /** *總迴圈的第一步判斷: * 1)i > 0:這裡固定的第一個元素無需與前一個固定元素進行判斷相等 * 2)nums[i] == nums[i - 1]:固定的後一個元素與前一個元素相等,則跳過 */ if(i > 0 && (nums[i] == nums[i - 1])) i++; /** *若總迴圈不需要跳過,則執行具體的比較程式碼 */ else { if(nums[i] > 0) break; //若固定的元素大於0,則直接結束本次迴圈 int target = 0 - nums[i]; //設定固定元素的相反數 if(nums[i] <= 0) //若固定元素小於0,則執行具體程式碼 { int m = i + 1; //設定指標m,指向固定元素的後面一位元素 int n = nums.size() - 1;//設定指標n,指向最後一位元素 while(m < n) //進行迴圈判斷(只有m < n才能遍歷所有) { if(nums[m] + nums[n] == target) //判斷,若滿足條件 { /** * 裡層判斷:1)m > 0, n < (nums.size() - 1)這是對固定元素的是否重複的判斷 * 若兩個指標均移動一位後,與之前兩個元素都相等,則兩個指標都要移動, * 若只移動一個則一定不會滿足相等條件,或者重複 */ if(m > 0 && nums[m] == nums[m - 1] && n < (nums.size() - 1) && nums[n] == nums[n + 1]) { ++m; --n; } else { //vec_result.insert(vec_result.begin(), nums[i]); //vec_result.insert(vec_result.begin() + 1, nums[m]); //vec_result.insert(vec_result.begin() + 2, nums[n]); //vec_result.erase(vec_result.begin() + 3, vec_result.end()); result.push_back({nums[i], nums[m], nums[n]}); //vec_result.erase(vec_result.begin(), vec_result.end()); ++m; --n; } } if(nums[m] + nums[n] < target) ++m; //並列判斷條件 if(nums[m] + nums[n] > target) --n; //並列判斷條件 } } i++; //移動固定元素 } } //sort(result.begin(), result.end()); //result.erase(unique(result.begin(), result.end()), result.end()); return result; }