题目:传送门
题意: 给定一个数组,选出其中三个数,使其和为0,并且不能重复。
思路: 首先为了保证结果不能重复,我们可以先对数组排序,然后先确定第一个数,然后找后两个数,因为数组有默认的排序,这样就保证了在循环过程中不会出现相同的结果,我们只需要保证第一个数不同,就能够保证结果不重复,并且三个数和为0,第一个数必须小于0,在寻找后两个数时,我们可以使用双指针来移动寻找。
代码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums);
};
vector<vector<int>> Solution::threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());///从小到大排序
int n = nums.size();
vector<vector<int>>ans;
for (int i = 0; i < n; i++) {
if (nums[i] > 0)///三个数之和为0,第一个数必须小于等于0
return ans;
if (i > 0 && nums[i] == nums[i - 1])///排除相同的结果,nums从小到大排序,只要第一个数不相等,结果就不等
continue;
int j = i + 1,k = n - 1;
while (j < k) {
if (nums[i] + nums[j] + nums[k] < 0) {
j++;
while (j<n&&nums[j] == nums[j - 1]) {
j++;///排除相同结果
}
}
else if (nums[i] + nums[j] + nums[k] > 0) {
k--;
while (k>0&&nums[k] == nums[k + 1]) {
k--;
}
}
else {
ans.push_back({
nums[i],nums[j],nums[k] });
k--;
while (k>0&&nums[k] == nums[k + 1]) {
k--;
}
}
}
}
return ans;
}
int main() {
vector<int>nums;
vector<vector<int>>ans;
while (1) {
int n;
cin >> n;
nums.push_back(n);
if (cin.get() == '\n')
break;
}
Solution A;
ans = A.threeSum(nums);
for (int i = 0; i < ans.size(); i++)
{
cout << ans[i][0] << " " << ans[i][1] <<" "<< ans[i][2] << endl;
}
return 0;
}