题目:
给定一个数组 nums ,从中找到 和为 0 的三个数之和的组合数有多少个
比如: 8 , 9 , 5 , 7, 8,-1,-3,-5,1,2
组合数: {8,-3,-5}
{-3, 1 , 2}
思路如下:
先将数组 nums 从大到小排序。
利用双指针法。先定位第一个指针,start 指向数组的第一个元素。 第二个指针 left 指向下标为 start + 1 的元素,第三个指针 right 指向 nums.length-1 。
判断此时 sum = nums[ start ] + nums[ left] + nums[ right] 的大小
若是 sum < 0, 则 left++;
若是 sum >0, 则 right --;
若是 sum == 0 , 则 找到该组合。
注意要进行去重,去重原则是
要保证连续重复的几个元素出现时候,第一个重复的元素不要做去重,要能参与算法,否则会丢失元素
java 代码如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
// 1 数组排序
Arrays.sort(nums);
for(int num:nums){
System.out.print(num+"\t");
}
System.out.println();
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < nums.length-2; i++) {
while (i-1>=0 && i<nums.length-2&& nums[i-1] == nums[i]) {
i++;
}
int left = i + 1;
int right = nums.length - 1;
//System.out.println("i= "+i+", left="+left+", right = "+right);
while (left < right) {
// 如果和
if (nums[i] + nums[left] + nums[right] < 0) {
left++;
} else if (nums[i] + nums[left] + nums[right] > 0) {
right--;
} else if(nums[i] + nums[left] + nums[right] == 0){
System.out.println("i= "+i+", left="+left+", right = "+right);
List<Integer> subList = new ArrayList<>();
subList.add(nums[i]);
subList.add(nums[left]);
subList.add(nums[right]);
result.add(subList);
left++;
right--;
//去除重复数据
while (left < right && left-1>0 &&nums[left] == nums[left-1]) {
left++;
}
while (right>left && right+1<nums.length && nums[right] == nums[right + 1]) {
right--;
}
}
}
}
return result;
}
}