力扣算法 Java 刷题笔记【nSum 问题】hot100(一)团灭 nSum 3

1. 两数之和(简单)

地址: https://leetcode-cn.com/problems/two-sum/
2022/02/11
做题反思:
方法一:暴力穷举 也可这么写 if (nums[i] + nums[j] == target && i != j)

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums[j] == target) {
                    return new int[] {i, j};
                }
            }
        }
        return new int[] {-1, -1};
    }
}

在这里插入图片描述

方法二:HashMap 减少时间复杂度

class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer, Integer> index = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            index.put(nums[i], i);
        }

        for (int j = 0; j < nums.length; j++) {
            int other = target - nums[j];
            if (index.containsKey(other) && index.get(other) != j) {
                return new int[] {j, index.get(other)};
            }
        }
        return new int[] {-1, -1};
    }
}

在这里插入图片描述

方法三:双指针(适用于有序数组)

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int slow = 0, fast = nums.length - 1;
        while (slow < fast) {
            int sum = nums[slow] + nums[fast];
            if (sum < target) {
                slow++;
            }
            if (sum > target) {
                fast--;
            }
            if (sum == target) {
                return new int[]{nums[slow], nums[fast]};
            }
        }
        return null;
    }
}

2. 三数之和(中等)

地址: https://leetcode-cn.com/problems/3sum/
2022/02/13
做题反思:短路运算 while (i < nums.length - 1 && nums[i] == nums[i + 1])

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        return nSumTarget(nums, 3, 0, 0);
    }
    
    List<List<Integer>> nSumTarget(int[] nums, int n, int start, int target) {
        List<List<Integer>> res = new LinkedList<>();
        if (n < 2 || nums.length < n) {
            return res;
        }
        if (n == 2) {
            int l = start, r = nums.length - 1;
            while (l < r) {
                int left = nums[l], right = nums[r];
                int sum = left + right;
                if (sum == target) {
                    res.add(Arrays.asList(left, right));
                    while (l < r && nums[l] == left) {
                        l++;
                    }
                    while (l < r && nums[r] == right) {
                        r--;
                    }
                }
                if (sum < target) {
                    l++;
                }
                if (sum > target) {
                    r--;
                }
            }
        }
        if (n > 2) {
            for (int i = start; i < nums.length; i++) {
                List<List<Integer>> tuples = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
                for (List<Integer> tuple : tuples) {
                    List<Integer> t = new LinkedList<>(tuple);
                    t.add(nums[i]);
                    res.add(t);
                } 
                while (i < nums.length - 1 && nums[i] == nums[i + 1]) {
                    i++;
                }
            }
        }
        return res;
    }
}

3. 四数之和(中等)

地址: https://leetcode-cn.com/problems/4sum/
2022/02/14
做题反思:

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        return nSumTarget(nums, 4, 0, target);
    }

    List<List<Integer>> nSumTarget(int[] nums, int n, int start, int target) {
        List<List<Integer>> res = new LinkedList<>();
        if (n < 2 || nums.length < n) {
            return res;
        }
        if (n == 2) {
            int l = start, r = nums.length - 1;
            while (l < r) {
                int left = nums[l], right = nums[r];
                int sum = left + right;
                if (sum == target) {
                    res.add(Arrays.asList(left, right));
                    while (l < r && nums[l] == left) {
                        l++;
                    }
                    while (l < r && nums[r] == right) {
                        r--;
                    }
                }
                if (sum < target) {
                    l++;
                }
                if (sum > target) {
                    r--;
                }
            }
        }
        if (n > 2) {
            for (int i = start; i < nums.length; i++) {
                List<List<Integer>> tuples = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
                for (List<Integer> tuple : tuples) {
                    List<Integer> t = new LinkedList<>(tuple);
                    t.add(nums[i]);
                    res.add(t);
                }
                while (i < nums.length - 1 && nums[i] == nums[i + 1]) {
                    i++;
                }
            }
        }
        return res;
    }
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心海非海_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值