1.力扣C++源码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int len = nums.size();
if (len < 3)return {
};//特判1,数组元素<3,返回空数组
vector<vector<int>> ans;//定义一个vector类型的二维数组存储符合的结果数组
sort(nums.begin(), nums.end());//默认升序
for (int a = 0; a < len - 2; a++) {
//固定外层循环
if (nums[a] > 0)return ans;//特判2,当a>0时,就停止循环,返回结果
if (a > 0 && nums[a] == nums[a - 1])continue;//去重,跳到循环开始处
int b = a + 1;//定义左指针b
int c = len - 1;//定义右指针c
while (b < c) {
//当b<c的时候,继续循环;b>=c的时候就停止指针移动
if (nums[b] + nums[c] > -nums[a])c--;//数太大了,c指针左移
else if (nums[b] + nums[c] < -nums[a])b++;//数太小了,b指针右移
else {
//正好=0
ans.push_back(vector<int>{
nums[a], nums[b], nums[c]});
c--;
b++;
//双指针缩小空间时,也需要考虑去重
//例如:[-4,1,1,1,2,3,3,3], a=0, b=1, c=7
while (b < c && nums[c] == nums[c + 1])c--;//右去重
while (b < c && nums[b] == nums[b - 1])b++;//左去重
}
}
}
return ans;
}
};
2.题解
//算法思路:排序 + 双指针
//1特判,对于数组长度 len,如果数组为 null 或者数组长度小于 3,返回[]。
//2对数组进行排序。
//3遍历排序后数组:
//(1)若 nums[i] > 0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
//(2)对于重复元素:跳过,避免出现重复解
//(3)令左指针 b = a + 1,右指针 c = len - 1,当 b < c 时,执行循环:
// 1>当 nums[a] + nums[b] + nums[c] == 0 执行循环,判断左界和右界是否和下一位置重复,
// 去除重复解。并同时将 b, c 移到下一位置,寻找新的解
// 2>若和大于 0,说明 nums[c] 太大,c 左移,即 c–;
// 3>若和小于 0,说明 nums[b] 太小,b 右移,即 b++;
3.VS可运行源码
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<vector>
#include<algorithm>
#pragma warning(disable:4996)
using namespace std;
//算法思路:排序 + 双指针
//1特判,对于数组长度 len,如果数组为 null 或者数组长度小于 3,返回[]。
//2对数组进行排序。
//3遍历排序后数组:
//(1)若 nums[i] > 0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
//(2)对于重复元素:跳过,避免出现重复解
//(3)令左指针 b = a + 1,右指针 c = len - 1,当 b < c 时,执行循环:
// 1>当 nums[a] + nums[b] + nums[c] == 0 执行循环,判断左界和右界是否和下一位置重复,
// 去除重复解。并同时将 b, c 移到下一位置,寻找新的解
// 2>若和大于 0,说明 nums[c] 太大,c 左移,即 c–;
// 3>若和小于 0,说明 nums[b] 太小,b 右移,即 b++;
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int len = nums.size();
if (len < 3)return {
};//特判1,数组元素<3,返回空数组
vector<vector<int>> ans;//定义一个vector类型的二维数组存储符合的结果数组
sort(nums.begin(), nums.end());//默认升序
for (int a = 0; a < len - 2; a++) {
//固定外层循环
if (nums[a] > 0)return ans;//特判2,当a>0时,就停止循环,返回结果
if (a > 0 && nums[a] == nums[a - 1])continue;//去重,跳到循环开始处
int b = a + 1;//定义左指针b
int c = len - 1;//定义右指针c
while (b < c) {
//当b<c的时候,继续循环;b>=c的时候就停止指针移动
if (nums[b] + nums[c] > -nums[a])c--;//数太大了,c指针左移
else if (nums[b] + nums[c] < -nums[a])b++;//数太小了,b指针右移
else {
//正好=0
ans.push_back(vector<int>{
nums[a], nums[b], nums[c]});
c--;
b++;
//双指针缩小空间时,也需要考虑去重
//例如:[-4,1,1,1,2,3,3,3], a=0, b=1, c=7
while (b < c && nums[c] == nums[c + 1])c--;//右去重 这里注意c+1
while (b < c && nums[b] == nums[b - 1])b++;//左去重 这里注意b-1
}
}
}
return ans;
}
};
int main()
{
printf("输入数组元素个数:");
int n;
scanf("%d", &n);
printf("输入数组元素:");
vector<int> nums;
int num;
for (int i = 0; i < n; i++) {
scanf("%d", &num);
nums.push_back(num);
}
//for (int i = 0; i < n; i++) {
// printf("%d ", nums[i]);//vector用下表访问元素
//}
Solution test;//定义类变量test,用test调用相应函数
vector<vector<int>> ans = test.threeSum(nums);//ans相当于一个二维数组
for (int i = 0; i < ans.size(); i++) {
//ans.size():ans中的vector容器的个数(二位数组行数)
for (int j = 0; j < ans[i].size(); j++) {
//ans[i].size():ans中第i个vector容器的长度(每个vector中元素个数)
printf("%d ", ans[i][j]);//vector用下表访问元素
}
printf("\n");
}
return 0;
}