一. 题目

二. 思路

  • 先排序。

  • i、j指针双重循环枚举两个数,然后算出需要的nums[k]值。对于固定的i,当j增大时,nums[k]的值一定减小,具有单调性。

  • 用HashSet去去重,时间复杂度为O(n^2 logn)

三. 代码

class Solution
{
    public List<List<Integer>> threeSum(int[] nums)
    {
        Arrays.sort(nums);
        Set<List<Integer>> ans = new HashSet<>();

        for (int i = 0, k = nums.length - 1; i < nums.length; ++i, k = nums.length - 1)//每次对于新i更新k
            for (int j = i + 1; j < nums.length; ++j)
            {
                int v = 0 - (nums[i] + nums[j]);
                while (nums[k] > v && k > j) --k;//当k值较大时,较小不用管
                for (boolean isAdd = false; nums[k] == v && k > j; --k)
                    if (!isAdd)//优化相同值只需要加一次,非常明显
                    {
                        isAdd = true;
                        ans.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    }
            }
        return ans.stream().toList();
    }
}