終於做了決定,開始做LeetCode,上來先做了3題都是關於sum的,這三題我認爲都是從同一個問題變過來的,很多人都知道一個經典的問題就是給你一個數組a和一個數字tar,問你這個數組中有沒有兩個數的和等於這個給定的數字tar,顯然要用O(N)的方法,這個問題的答案就是先排序,然後定義兩個邊界l和r,l一開始等於0,r一開始等於n-1,每次把邊界指的兩個數相加和給定的數tar比較一下,如果比tar小,那麼l++,比tar大,那麼r--,如果等於那麼l++,r--。那麼問題來了,爲什麼a[l]+a[r]<tar的時候,只需要l++就好了,這是這個做法的關鍵,這是因爲當a[l]+a[r]<tar的時候,肯定有a[l]+a[k]<=a[l]+a[r]<tar,k=[l+1,r-1],因爲數組是排好序的。同理也可以說明r--的原因。
這樣說來的話,可以用O(N)的方法解決數組中是否有2個數的和等於給定一個數的問題,那麼三個數只需要枚舉一個數a[i],用這個tar減去枚舉的這個數,然後再用O(N)的時間判斷剩下的數有沒有兩個數的和等於tar-a[i]。時間複雜度是O(N*N)。
還有一個問題就是判重,實話說判重花了我很多時間。主要就是有兩點:
第一,枚舉i後,j一定是i+1開始枚舉。
第二,對於枚舉的i,j,k如果我發現當前枚舉的量和上次循環枚舉的值是相等的。那麼這次直接continue。
3sum的代碼如下:
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
int i ,j,k;
int n=num.size();
vector<int>ans;
vector<vector<int> >cl;
sort(num.begin(),num.end());
for(i=0;i<n;i++)
{
if(num[i]==num[i-1]&&i>0)
continue;
for(j=i+1,k=n-1;j<k;)
{
if(num[j]==num[j-1]&&j>i+1)
{
j++;
continue;
}
if(num[k]==num[k+1]&&k<n-1)
{
k--;
continue;
}
if(num[j]+num[k]+num[i]==0)
{
ans.push_back(num[i]);
ans.push_back(num[j]);
ans.push_back(num[k]);
cl.push_back(ans);
ans.clear();
j++;
k--;
}
else if(num[j]+num[k]+num[i]<0)
j++;
else
k--;
}
}
return cl;
}
};
3sumclosest 代碼如下:
class Solution {
int abs(int x)
{
return x>0?x:-x;
}
public:
int threeSumClosest(vector<int> &num, int target) {
int n=num.size();
int i,j,k;
sort(num.begin(),num.end());
int min=100000000;
int ans;
for(i=0;i<n;i++)
{
for(j=i+1,k=n-1;j<k;)
{
if(abs(num[i]+num[j]+num[k]-target)<min)
{
min=abs(num[i]+num[j]+num[k]-target);
ans=num[i]+num[j]+num[k];
}
if(num[j]+num[k]+num[i]>target)
k--;
else if(num[j]+num[k]+num[i]<target)
j++;
else
return target;
}
}
return ans;
}
};
class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
int n=num.size();
vector<vector<int> >ans;
int i,k,j,l;
vector<int>tmp;
sort(num.begin(),num.end());
for(i=0;i<n;i++)
{
if(i>0&&num[i]==num[i-1])
continue;
for(j=i+1;j<n;j++)
{
if(j>i+1&&num[j]==num[j-1])
continue;
int sum=target-num[i]-num[j];
for(k=j+1,l=n-1;k<l;)
{
if(k>j+1&&num[k]==num[k-1])
{
k++;
continue;
}
if(l<n-1&&num[l]==num[l+1])
{
l--;
continue;
}
if(num[k]+num[l]==sum)
{
tmp.clear();
tmp.push_back(num[i]);
tmp.push_back(num[j]);
tmp.push_back(num[k]);
tmp.push_back(num[l]);
ans.push_back(tmp);
k++;
l--;
}
else if(num[k]+num[l]<sum)
k++;
else
l--;
}
}
}
return ans;
}
};