leetcode 15. 3Sum
1,思考问题时一定要发散,基于固有的经验
2,解题思路
a,数据结构(容器)
b,基本算法(搜索,匈牙利,并查集,动态规划,网络流)
c,基本算法思想(贪心,分支)
3,本题刚开始想的是用快排后使用map,复杂度是O(n2),超时,代码如下
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { int countIn,countOut; int length = nums.size() - 1; int temp; int place = 0; vector<int> resultTemp; vector<vector<int>> result; map<int,int> unMap; if(length < 2) return result; quickSort(nums,0,length); for(countIn = 0 ; countIn <= length ; countIn ++){ unMap[nums[countIn]] = countIn; if(countIn != length) if(nums[countIn] < 0 && nums[countIn + 1] >= 0) place = countIn; } for(countOut = 0 ; countOut <= place ; countOut ++){ if(countOut != 0 && nums[countOut] == nums[countOut -1]) continue; for(countIn = length ; countIn >= place ; countIn --){ temp = 0 - (nums[countOut] + nums[countIn]); if(unMap.find(temp) != unMap.end() && unMap[temp] > countOut && unMap[temp] < countIn){ resultTemp.push_back(nums[countOut]); resultTemp.push_back(temp); resultTemp.push_back(nums[countIn]); result.push_back({nums[countOut] , temp , nums[countIn]}); } } } return result; }; void quickSort(vector<int>& nums, int low, int high){ int left,right; int where; int place; left = low; right = high; where = 1; place = nums[left]; if(left >= right) return ; while(left < right){ if(where == 1){ if(place > nums[right]){ nums[left] = nums[right]; left += 1; where = 0; }else{ right -= 1; } }else{ if(place < nums[left]){ nums[right] = nums[left]; right -= 1; where = 1; }else{ left += 1; } } } nums[left] = place; quickSort(nums, low, left-1); quickSort(nums, left+1, high); }; };
4,后来看的网上解法,左右夹逼的方法,也是O(n2)
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { int countOut,left,right; int length = nums.size() - 1; int sum; vector<int> resultTemp; vector<vector<int>> result; if(length < 2) return result; quickSort(nums,0,length); for(countOut = 0 ; countOut <= length ; countOut ++){ if(countOut != 0 && nums[countOut] == nums[countOut -1]) continue; left = countOut + 1; right = length; while(left < right){ sum = nums[countOut] + nums[left] + nums[right]; if(sum == 0){ result.push_back({nums[countOut] , nums[left] , nums[right]}); while(++left < right && nums[left] == nums[left - 1]); while(--right > left && nums[right] == nums[right + 1]); }else if(sum < 0){ left ++; }else if(sum > 0){ right --; } } } return result; }; void quickSort(vector<int>& nums, int low, int high){ int left,right; int where; int place; left = low; right = high; where = 1; place = nums[left]; if(left >= right) return ; while(left < right){ if(where == 1){ if(place > nums[right]){ nums[left] = nums[right]; left += 1; where = 0; }else{ right -= 1; } }else{ if(place < nums[left]){ nums[right] = nums[left]; right -= 1; where = 1; }else{ left += 1; } } } nums[left] = place; quickSort(nums, low, left-1); quickSort(nums, left+1, high); }; };