题目
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
先排除边界情况,如数组长度小于3则直接返回。
可以先对数组进行排序,时间复杂度为O(nlogn),接着从左向右选一个数做为基准pivot,接着将基准数右边的数组的两端取L和R向中间遍历,获得其和result = piovt + L + R。
- 若result等于0,则将数据加入结果集
- 若result小于0,说明需要将L增加,因此将L的指针向右移
- 若result大于0,说明需要将R减少,因此将R的指针向左移
注:需要对pivot、L和R进行去重,当当前遍历的数与上一个数相同时需要将指针移动
解答(C#)
public class Solution {
public IList<IList<int>> ThreeSum(int[] nums) {
IList<IList<int>> ans = new List<IList<int>>();
if(nums == null || nums.Length < 3)
return ans;
Array.Sort(nums);//先从小到大排序
int L, R = 0;
int Length = nums.Length;
//从小到大遍历
for(int i = 0 ; i < Length - 2; i++){
if(nums[i] > 0)break; //若该数大于0,那么右边两数一定大于0,因此结束
//基底数去重
if(i > 0 && nums[i] == nums[i - 1])
continue;
L = i + 1;
R = Length - 1;
while(L < R){
//左右两数去重
if(nums[i] + nums[L] + nums[R] == 0)
{
ans.Add(new List<int>{nums[i], nums[L], nums[R]});
while(L < R && nums[L] == nums[L+1]) L++;
while(L < R && nums[R] == nums[R-1]) R--;
L++;
R--;
}
else if(nums[i] + nums[L] + nums[R] > 0)
R--;
else if(nums[i] + nums[L] + nums[R] < 0)
L++;
}
}
return ans;
}
}