一、题目链接
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
二、自己的思路
说实话我就没啥思路,能力摆在这里,我能想到的就是暴力破解,然后写出屎山代码,其实这个代码也是参考了答案思路之后才写出来的:
最初的代码就是三个循环嵌套,然后也没有排序,整出来自然而然,就是很多重复的。然后我参考了答案的思路,自己写了个排序,排序结束之后在每个循环之后加入一个判断条件,也就是nums[fast] != nums[fast-1],遇到和之前重复的就跳过去。
但是这个代码是超时的,毕竟……暴力解,早就预想到了。
三、现在的解法
之后参考答案写一个双指针,看了思路之后感觉好像很简单,当时写的时候脑瓜子宕机。
简单来说,第一个指针first遍历,first之后就是second第二个数值,同时声明一个third指针指向数组的最后位置,first每遍历一个数字,second就从first所在位置往后走,同时third从数组右边往左走,一直到三个数之和为0,然后把对应的数组的值添加到数组之中(唉,真的写的很烂,而且还很慢)。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> A;
for(int i = 0;i<nums.size();i++)
{
for(int j = 0;j<nums.size();j++)
{
if(nums[i]<nums[j])
{
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}
}
for(int fast = 0;fast<nums.size();fast++)
{
if(fast==0 || nums[fast]!=nums[fast-1])
{
int i = nums.size()-1;
for(int slow= fast+1;slow<nums.size();slow++)
{
if(slow==fast+1 || nums[slow]!=nums[slow-1])
{
while(nums[fast]+nums[slow]+nums[i]>0 && i> slow+1)
{
i--;
}
if(nums[i]+nums[fast]+nums[slow]==0&& slow!=i)
{
vector<int> B {};
B.push_back(nums[fast]);
B.push_back(nums[slow]);
B.push_back(nums[i]);
A.push_back(B);
}
}
}
}
}
return A;
}
};
四、围观大神
第一个,写的比较好的双指针,起码思路比我清晰
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
// 枚举 a
for (int first = 0; first < n; ++first) {
// 需要和上一次枚举的数不相同
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
// c 对应的指针初始指向数组的最右端
int third = n - 1;
int target = -nums[first];
// 枚举 b
for (int second = first + 1; second < n; ++second) {
// 需要和上一次枚举的数不相同
if (second > first + 1 && nums[second] == nums[second - 1]) {
continue;
}
// 需要保证 b 的指针在 c 的指针的左侧
while (second < third && nums[second] + nums[third] > target) {
--third;
}
// 如果指针重合,随着 b 后续的增加
// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if (second == third) {
break;
}
if (nums[second] + nums[third] == target) {
ans.push_back({nums[first], nums[second], nums[third]});
}
}
}
return ans;
}
};
力扣显示耗时最短的,马上去啃!!
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
vector<vector<int>> ans;
if(nums.size() < 3) return ans;
int min = 200000, max = -200000;
for (int i = 0; i < nums.size(); i++) {
if(min > nums[i]) min = nums[i];
if(max < nums[i]) max = nums[i];
}
const int range = -min, size = max-min+1;
char store[size];
for (int i = 0; i < size; i++) store[i] = 0;
for (int i = 0; i < nums.size(); i++) if(store[nums[i]+range] < 3) store[nums[i]+range]++;
int len = 0;
for (int i = 0, j = 0; i < size; i++) {
if(store[i] > 0) {
nums[j++] = i-range;
len++;
}
}
vector<int>& unique = nums;
vector<int> soln(3,0);
if(unique[0] > 0 || unique[len-1] < 0) return ans;
else if(len == 1) {
if(unique[0]==0 && store[range]>2) ans.push_back(soln);
return ans;
}
const int high = unique[len-1], zero = store[range];
for (int i = 0; i < len; i++) {
int a = unique[i];
if(a > 0) break;
int j = (store[a+range] > 1) ? i : i+1;
for (; j < len; j++) {
int b = unique[j];
int c = -a-b;
if (b > -a/2) break;
else if(c > high || c < b) continue;
else if(c == b) {
if((c==0 && zero>=3) || (c!=0 && store[c+range]>=2)) {
soln[0] = a;
soln[1] = b;
soln[2] = c;
ans.push_back(soln);
}
}
else {
if(store[c+range]) {
soln[0] = a;
soln[1] = b;
soln[2] = c;
ans.push_back(soln);
}
}
}
}
return ans;
}
};
五、感想
基础不牢,写的太少,前路坎坷,还是多刷题多思考叭。