Java做算法:三数之和
题目:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。
输入:nums = [-1,0,1,2,-1,-4]
输出:[ [-1,-1,2], [-1,0,1] ]
解答此题的关键思路:用左右指针查找 nums[ i ] 的三元组,左右指针要位于 i 的右边。
详细步骤:
- 创建一个列表存储结果。
- 把数组元素从小到大排序,便于移动双指针和去重。
- 然后 i 遍历数组,遍历到相同的数字(已经查找过这个数的三元组)则跳出本次循环,遍历下一个数,防止找到重复的三元组。
- 设置while循环,查找此数的所有三元组:三个数分别为 nums[ i ], nums[ left ], nums[ right ],计算和。
- 如果和为 0,则添加到列表,并且同时移动左右指针,为了查找此数的其他三元组。写while循环判断如果下一个指针的元素相同,要继续移动到不同为止。
- 如果和小于 0 或大于 0,则分别移动左右指针。
我的代码:
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++)
{
//如果最小数字大于0,则没有计算的必要了
if(nums[i]>0)
break;
// 如果此数与上一个元素相同,则跳出本轮循环,直到元素不同为止
if(i>0 && nums[i]==nums[i-1])
continue;
int left = i+1; // left必须位于i的右边,防止重复三元组
int right = nums.length-1;
while(left<right)
{
int sum = nums[i]+nums[left]+nums[right];
if(sum==0)
{
result.add(Arrays.asList(nums[i],nums[left],nums[right]));
left++;
right--;
// 移动指针后,要判断移动后的元素是否与上一个相同!!并且要先判断left<right,不然会死循环。
while(left<right && nums[left-1]==nums[left])
{ left++; }
while(left<right && nums[right+1]==nums[right])
{ right--; }
}
// 如果和小于0,则移动左指针;大于0,则移动右指针。目的是让指针遍历完剩下的元素。
else if(sum<0)
{
left++;
}
else
{
right--;
}
}
}
return result;
}
所有正文内容皆为本人原创,禁止搬运

浙公网安备 33010602011771号