0
点赞
收藏
分享

微信扫一扫

[数组]BM54 三数之和-中等

​​BM54 三数之​​

描述

给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。

数据范围:[数组]BM54 三数之和-中等_双指针,数组中各个元素值满足 [数组]BM54 三数之和-中等_双指针_02空间复杂度:[数组]BM54 三数之和-中等_三数之和_03,时间复杂度 [数组]BM54 三数之和-中等_三数之和_03

注意:

  1. 三元组(a、b、c)中的元素可以按任意顺序排列。
  2. 解集中不能包含重复的三元组。

示例1

输入:

[-10,0,10,20,-10,-40]

复制返回值:

[[-10,-10,20],[-10,0,10]]

复制

示例2

输入:

[-2,0,1,1,2]

复制返回值:

[[-2,0,2],[-2,1,1]]

复制

示例3

输入:

[0,0]

复制返回值:

[]

题解

方法一:暴力求解

略~~

方法二:先排序,然后再使用双指针求解

假设数组为num,长度为n

步骤:

  1. 先将按升序数组排序
  2. 从索引i=0到i=n - 2进行遍历,索引为i的值为num[i],假设存在另外索引k,j的值满足num[i] + num[k] + num[j] = 0,那么只需要在[i+1,n-1]区间找到两个数字满足num[k] + num[j] == - num[i]即可
  3. 通过第二步分析,三数之和变成了两数之和。假设索引k < j,那么一定有num[k] < num[j],假设num[k] + num[j] = val
  1. 当val == -num[i]的时候直接返回i,k,j
  2. 当val > -num[i]的时候说明k、j的和过大,要在该区间找一个比较小的和,此时只能将j左移,因为如果k右移会导致num[k]增大
  3. 如果val < -num[i],则k右移
  4. 如果val == -num[i],则应该将后序数组中和num[k]、num[j]值相等的索引也跳过
  1. 在求解的过程中要做去重,假设我们已经将索引为i处的进行了求解,那么 如果num[i + 1] == num[i]则可以直接跳过,因为这些都是重复的解

代码如下:

#include <bits/stdc++.h>

std::vector<std::vector<int>> threeSum(std::vector<int> &num)
{
std::vector<std::vector<int>> ans;
if (num.size() < 3)
{
return ans;
}
std::sort(num.begin(), num.end());
for (int i = 0; i < num.size() - 2; ++i)
{
if (i > 0 && num[i] == num[i - 1])
{
continue;
}
int left = i + 1;
int right = num.size() - 1;
while (left < right)
{
int target = -num[i];
int sum = num[left] + num[right];
if (sum == target)
{
ans.push_back({num[i], num[left], num[right]});
while (left + 1 < right && num[left] == num[left + 1])
{
left++;
}

while (right - 1 > left && num[right] == num[right - 1])
{
right--;
}
left++;
right--;
}
else if (sum > target)
{
right--;
}
else
{
left++;
}
}
}
return ans;
}
举报

相关推荐

0 条评论