15. 三数之和(Java)(三指针,滑动窗口)

1 题目

给你一个包含 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2 Java

2.1 方法一(三指针,滑动窗口)

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<Integer> list = new ArrayList<>();
        List<List<Integer>> listList = new ArrayList<>();
        Arrays.sort(nums);
        int target = 0;

        // 固定第一个元素,向右遍历
        for(int i = 0; i < nums.length - 2 && nums[i] <= target; i++){
            
            // 在[i, nums.length - 1]内,双指针+滑动窗口,找剩余两个元素
            int l = i + 1, r = nums.length - 1, iNum = nums[i], subTarget = target - nums[i];
            while(l < r){
                int lNum = nums[l], rNum = nums[r];
                if(lNum + rNum == subTarget){
                    // 记录结果
                    list.add(iNum);  list.add(lNum);  list.add(rNum);  listList.add(new ArrayList<Integer>(list));
                    list.clear();
                    // 避免重复结果,l、r移动至下一个值(越过相同值)
                    while(nums[l] == lNum && l < r)  l++;
                    while(nums[r] == rNum && l < r)  r--;
                }
                else if(lNum + rNum < subTarget)   l++;
                else if(lNum + rNum > subTarget)   r--;
            }

            // 避免重复结果,i移动至下一个值(越过相同值)
            while(i < nums.length - 1 && nums[i + 1] == iNum)  i++;
        }

        return listList;
    }
}

化简

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<Integer> list = new ArrayList<>();
        List<List<Integer>> listList = new ArrayList<>();
        Arrays.sort(nums);
        int target = 0;

        // 固定第一个元素,向右遍历
        for(int i = 0; i < nums.length - 2 && nums[i] <= target; i++){
            // 避免重复结果,i移动至下一个值(越过相同值)
            if(i > 0 && nums[i - 1] == nums[i])  continue;

            // 同两数之和
            // 在[i, nums.length - 1]内,双指针+滑动窗口,找剩余两个元素
            int l = i + 1, r = nums.length - 1;
            while(l < r){
                int sum = nums[i] + nums[l] + nums[r];
                if(sum == target){
                    // 记录结果
                    list.add(nums[i]);  list.add(nums[l]);  list.add(nums[r]);  listList.add(new ArrayList<Integer>(list));  list.clear();
                    // 避免重复结果,l、r移动至下一个值(越过相同值)
                    while(l < r && nums[l] == nums[++l]);
                    while(l < r && nums[r] == nums[--r]);
                }
                else if(sum < target)   while(l < r && nums[l] == nums[++l]);
                else if(sum > target)   while(l < r && nums[r] == nums[--r]);
            }

        }

        return listList;
    }
}
发布了131 篇原创文章 · 获赞 0 · 访问量 2266

猜你喜欢

转载自blog.csdn.net/weixin_43969686/article/details/105296953