给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a ,b ,c ,使得 a + b + c = 0 ?请找出所有和为 0 且 不重复 的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
提示:
0 <= nums.length <= 3000
-105 <= nums[i] <= 105
这个题很简单的用双指针就行,把mid,rear当做双指针,依次遍历front,刚开始我比较贪心,想用一个while循环遍历一遍结束,但是发现在大数组的时候会超时,后来还是妥协,用一个for循环一个while循环来做。
正确答案:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
if (nums.size() < 3) return {};
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
int target = - nums[i];
int left = i + 1, right = nums.size() - 1;
while (left < right) {
int sum = nums[left] + nums[right];
if (sum == target) {
res.push_back({nums[i], nums[left], nums[right]});
while (left < right && nums[left] == nums[++left]);
while (left < right && nums[right] == nums[--right]);
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
return res;
}
};
超时答案:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
if(nums.size() < 3)
return res;
sort(nums.begin(),nums.end());
int front = 0, mid = 0, rear = nums.size()-1, flag = -1;;
mid = (front+rear)/2;
if(nums[front] == 0 && nums[rear] == 0)
{
res.push_back({0,0,0});
return res;
}
while(front+1 < rear)
{
if(0 == nums[front]+nums[mid]+nums[rear])
{
res.push_back({nums[front],nums[mid],nums[rear]});
rear--;
if (front + 1 == rear) break;
while (nums[rear] == nums[rear + 1] && rear > front+1)
rear--;
mid = (front + rear) / 2;
flag = -1;
}
else if(0 > nums[front]+nums[mid]+nums[rear])
{
if(flag == 0)
{
rear--;
if (front + 1 == rear) break;
while (nums[rear] == nums[rear + 1] && rear > front+1)
rear--;
mid = (front+rear)/2;
flag = -1;
continue;
}
mid++;
flag = 1;
if(mid == rear)
{
front++;
rear = nums.size() - 1;
if (front + 1 == rear) break;
while (nums[front] == nums[front - 1]&& rear > front + 1)
{
front++;
}
mid = (front + rear) / 2;
flag = -1;
}
}
else if(0 < nums[front]+nums[mid]+nums[rear])
{
if(flag == 1)
{
rear--;
if (front + 1 == rear) break;
while (nums[rear] == nums[rear + 1] && rear > front+1)
rear--;
mid = (front+rear)/2;
flag = -1;
continue;
}
mid--;
flag = 0;
if(mid == front)
{
rear--;
while (nums[rear] == nums[rear + 1]&& rear > front+1)
{
rear--;
}
mid = (front + rear) / 2;
flag = -1;
}
}
}
return res;
}
};