15. 三数之和
题目描述:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解题思路(双指针解法):
三数之和转变成两数之和: a + b + c = 0 转成 a + b = -c。具体步骤:
1. 先对数组nums进行排序
2. 固定指针now是和c, 然后左指针从now前一个开始移动, hi指针从数组末端移动,
(1) nums[lo] + nums[hi] > nums[now] 则 hi指针向前移动1
(2) nums[lo] + nums[hi] < nums[now] 则 lo指针向后移动1
(3) nums[lo] + nums[hi] = nums[now], 将这三个值存到结果数组results中, lo和 hi 向前移动1,如果移动后的nums[lo]和nums[hi] 还等于它们之前的值,就继续向前移动。这是去重操作。
(4) lo > hi 跳出这层循环。
如果nums[now] 大于0, 则直接跳出循环结束返回结果results数组。

python实现
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
nums_len = len(nums)
results = []
for i, sumi in enumerate(nums):
if sumi > 0 :
break
if i > 0 and sumi == nums[i - 1]:
continue
negsum = 0 - sumi
low = i + 1
fast = nums_len - 1
while(low < fast):
if nums[low] + nums[fast] > negsum:
fast -= 1
elif nums[low] + nums[fast] < negsum:
low += 1
else:
results.append([sumi, nums[low], nums[fast]])
left = nums[low]
right = nums[fast]
while(nums[low] == left and low < fast):
low += 1
while(nums[fast] == right and low < fast):
fast -= 1
return results
C++实现
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
int nums_len = nums.size();
vector<vector<int>> results;
int k=0;
while(k < nums_len - 2){
int c = nums[k];
if(c > 0) break;
int neg_c = 0 - c;
int lo = k + 1;
int hi = nums_len - 1;
while(lo < hi){
int a = nums[lo];
int b = nums[hi];
if(a + b > neg_c) hi--;
else if(a + b < neg_c) lo++;
else{
vector<int> result{c, a, b};
results.push_back(result);
while(nums[lo] == a && lo < hi) lo++;
while(nums[hi] == b && lo < hi) hi--;
}
}
while(nums[k] == c && k < nums_len - 2) k++;
}
return results;
}
};
java实现:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
int nums_len = nums.length;
List<List<Integer>> results = new ArrayList();
int k=0;
while(k < nums_len - 2){
int c = nums[k];
if(c > 0) break;
int neg_c = 0 - c;
int lo = k + 1;
int hi = nums_len - 1;
while(lo < hi){
int a = nums[lo];
int b = nums[hi];
if(a + b > neg_c) hi--;
else if(a + b < neg_c) lo++;
else{
List<Integer> result = new ArrayList();
result.add(c);
result.add(a);
result.add(b);
results.add(result);
while(nums[lo] == a && lo < hi) lo++;
while(nums[hi] == b && lo < hi) hi--;
}
}
while(nums[k] == c && k < nums_len - 2) k++;
}
return results;
}
}

本文介绍了如何使用双指针法解决给定整数数组中找到所有和为0的三元组的问题。通过排序数组,固定一个元素,然后用两个指针分别从两侧向中间移动,判断两数之和是否等于目标值,从而找到所有满足条件的三元组。文章提供了Python、C++和Java三种语言的实现代码。
485

被折叠的 条评论
为什么被折叠?



