Nsum之和全部解决

如果假设输入一个数组 nums 和一个目标和 target请你返回 nums 中能够凑出 target 的两个元素的值,比如输入 nums = [5,3,1,6], target = 9,那么算法返回两个元素 [3,6]

两数之和的核心步骤

lo为最左边的元素,hi为最右边的元素

有了上面的铺垫就来解决n数之和的问题了,比如一个三数之和你可以穷举一个数字然后调用二数之和,四数之和你可以穷举一个数字然后调用三数之和,那么N数之和呢?

总体就是n==2时的时候就用两数之和的解法,然后大的时候递归调用。

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

    private static   List<Integer> transferArrayToList(int[] array){
        List<Integer> transferedList = new ArrayList<>();
        Arrays.stream(array).forEach(arr -> transferedList.add(arr));
        return transferedList;
    }

    private static List<List<Integer>> nSumTarget(
    int[] nums, int n, int start, int target) {
    int sz = nums.length;
    List<List<Integer>> res =new ArrayList<>();
    // 至少是 2Sum,且数组大小不应该小于 n
    if (n < 2 || sz < n) return res;
    // 2Sum 是 base case
    if (n == 2) {
        // 双指针那一套操作
        int lo = start, hi = sz - 1;
        while (lo < hi) {
            int sum = nums[lo] + nums[hi];
            int left = nums[lo], right = nums[hi];
            if (sum < target) {
                while (lo < hi && nums[lo] == left) lo++;
            } else if (sum > target) {
                while (lo < hi && nums[hi] == right) hi--;
            } else {
                res.add(transferArrayToList(new int[]{nums[lo],nums[hi]}));
                while (lo < hi && nums[lo] == left) lo++;
                while (lo < hi && nums[hi] == right) hi--;
            }
        }
    } else {
        // n > 2 时,递归计算 (n-1)Sum 的结果
        for (int i = start; i < sz; i++) {
             List<List<Integer>>
                sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
            for (List<Integer> arr : sub) {
                // (n-1)Sum 加上 nums[i] 就是 nSum
                arr.add(nums[i]);
                res.add(arr);
            }
            while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
        }
    }
    return res;
}

}

此方法可用的前提是数组必须是排序的

  • 双指针那一块就不具体讲解了,
  • else语句里的这一块总体的意思就是,穷举一个数递归调用(n-1 )sum,
     List<List<Integer>>
                    sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);

    这句话的意思就是固定住一个数之后对后面的数进行递归调用,此时对于(n-1)sum的target来说就是target-nums[i]了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值