3Sum有关问题(a+b+c=0?)
3Sum问题(a+b+c=0?)
本题来自LeetCode中Problems 3sum。
问题描述:
输入:数组S={a1,a2,...,an},其中ai为任意整数,n为数组中元素数目
输出:序列对(a,b,c)组成的数组,使得a+b+c=0,其中a≤b≤c,且(a,b,c)序列不重复
eg:
输入:S={-1,0,1,2,-1,-4}
输出:(-1,0,1)、(-1,-1,2)
思路:1、由于要求a≤b≤c,由此可考虑先对整个数组按非递减排序,对于非递减的数组,可以从其两端依次扫描符合条件的序列对(a,b,c);2、设置三个指针,假设这三个指针p1,p2,p3指向的值分别为a,b,c,为满足a+b+c=0,则可固定住p1不变,p2,p3分别从数组的前(除第一个元素)端和后端开始扫描,若a+b+c>0,因数组是非递减的,肯定是因为此时c较大,此时应该--p2,若a+b+c<0,则是因为b较小,此时++p1,若a+b+c=0,则将其保存。
算法复杂度:O(n*n)
vector<vector<int> > threeSum(vector<int> &num) { // Note: The Solution object is instantiated only once and is reused by each test case. vector<vector<int>> vecRlt; if (num.size() < 3) { return vecRlt; } sort(num.begin(),num.end()); vector<int> vecTriple(3); int iFirst = 0; int iSecond = 0; int iThird = num.size() - 1; for (;iFirst < num.size() - 2 && num[iFirst] <= 0; ++iFirst) { iSecond = iFirst + 1; iThird = num.size() - 1; if (iFirst > 0 && num[iFirst] == num[iFirst-1]) { continue; } while (iSecond < iThird) { int iSum = num[iFirst] + num[iSecond]; if (iSum + num[iThird] > 0) { --iThird; } else if (iSum + num[iThird] < 0) { ++iSecond; } else { vecTriple[0] = num[iFirst]; vecTriple[1] = num[iSecond]; vecTriple[2] = num[iThird]; vecRlt.push_back(vecTriple); ++iSecond; --iThird; //消除后面重复的数 while(iSecond<iThird && num[iSecond] == num[iSecond-1]) { ++iSecond; } //消除前面重复的数 while(iSecond<iThird && num[iThird] == num[iThird+1]) { --iThird; } } } } return vecRlt; }