三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 abc 使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]

 

满足要求的三元组集合为:

[

[-1, 0, 1],

[-1, -1, 2]

]

    题目清晰,方法也很容易想出,先排序数组,拿一个指针作桩,再用两个指针进行寻找

    这里有三个可以优化的地方:

  1. 当指定一个数为桩,只要找他右边的数即可,因为左边的数的可能性之前已经完成了
  2. 当数组里面全是相同符号的数,就可以不用在找了
  3. 当桩到数组末尾全是相同符号的数,也可以不要再找了

这里的"桩"就是一个指针,如图绿色箭头所指,然后再创建出两个新的指针,根据当前

所得出的三数和,来判断下一步该干嘛

public static List<List<Integer>> threeSum(int[] nums) {
    Set<List<Integer>> resultSet = new LinkedHashSet<>();
    List<Integer> list = new LinkedList<>();
    List<List<Integer>> resultList = new LinkedList<>();
    int length = nums.length;
    if (length < 3) {
        return resultList;
    }
    Arrays.sort(nums);
    if (nums[0] <= 0 && nums[length - 1] >= 0) {
        for (int i = 0; i < length - 1; i++) {
            if (nums[i] > 0) {
                break;
            }
            int first = i + 1;
            int last = length - 1;
            while (first < last) {
                if ((long)nums[i] * nums[last] > 0) {//着重注意一下这里
                    break;
                }
                long res = nums[i] + nums[first] + nums[last];
                if (res == 0) {
                    list = new LinkedList<>();
                    list.add(nums[i]);
                    list.add(nums[first]);
                    list.add(nums[last]);
                    resultSet.add(list);
                }
                if (res <= 0) {
                    first++;
                } else {
                    last--;
                }
            }
        }
    }

    Iterator<List<Integer>> setIt = resultSet.iterator();
    while(setIt.hasNext()){
        resultList.add(setIt.next());
    }
    return resultList;
}

 

原文地址:https://www.cnblogs.com/figsprite/p/10935660.html