Leetcode 15.三数之和 双指针 or 暴力哈希
生活随笔
收集整理的這篇文章主要介紹了
Leetcode 15.三数之和 双指针 or 暴力哈希
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:傳送門
題目:給你一個包含 n 個整數的數組?nums,判斷?nums?中是否存在三個元素 a,b,c ,使得?a + b + c = 0 ?請你找出所有和為 0 且不重復的三元組。
暴力+Hash? ? ? ? ?
把所有數字用map記錄個數,然后排序,拍完序之后n2暴力枚舉兩個數,求第三個數在map里邊?不,然后怎么判是否有重復的方法就是把三個數直接hash,總體來說就是全部暴力,稍微加了一點點剪枝然后卡過去了。
時間復雜度 n2logn
const int mod =1e9+7;
class Solution {
int hash(int x,int y,int z){long long ans =1; ans = (ans*233+x)%mod;ans = (ans*234+y)%mod;ans = (ans*235+z)%mod;return ans;
}
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end());map<long long,int> have; //hashmap<int,int> m;//裝個數have.clear();m.clear();vector<vector<int>> ans;for(int i=0;i<nums.size();i++)m[nums[i]]++;int n = nums.size();if(n<3) return ans;for(int i=0;i<n-2;i++){for(int j=i+1;j<n-1;j++){int x=0-nums[i]-nums[j];//枚舉兩個數,求第三個數if(x<nums[j]) continue;if(m[x]-(nums[i]==x)-(nums[j]==x)>0) //看第三個數在map里邊不{int c=hash(nums[i],nums[j],x); //在就把三數丟到hashif(!have[c]){have[c]=1;ans.push_back({nums[i],nums[j],x});}}}m[nums[i]]--;}return ans;}
};
雙指針:
確實文盲了,看題解才知道這種應該是雙指針的題目,先對數組進行排序。
循環確定第一個數 i
雙指針指向第一個數字后邊的最小值和最大值的位置,l=i+1,r=n-1
然后判斷nums[i]+nums[l]+nums[r]是否為0,若小于零,左指針右移,大于零,右指針左移
相等就是左右指針同時往里移動
再加上判重,如果存在和為0,且當前左指針和他的下一個數相同,直接把左指針右移,右指針相反的。
代碼如下:
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {int n = nums.size();vector<vector<int>> ans;if(n<3) return ans;sort(nums.begin(),nums.end());for(int i=0;i<n-2;i++){//剪枝if(nums[i]>0) break;if(i>0&&nums[i]==nums[i-1])continue;int l=i+1,r=n-1;while(l<r){if(nums[i]+nums[l]+nums[r]==0){while(l<r && nums[l+1]==nums[l]) l++;while(l<r && nums[r-1]==nums[r]) r--;ans.push_back({nums[i],nums[l],nums[r]});l=l+1;r=r-1;}else if(nums[i]+nums[l]+nums[r]<0)l=l+1;else r=r-1;}}return ans;}
};// -4 -1 -1 0 1 2
總結
以上是生活随笔為你收集整理的Leetcode 15.三数之和 双指针 or 暴力哈希的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Leecode 1583.统计不开心的朋
- 下一篇: Leetcode 526.优美的排列 二