【LeetCode】升级打怪之路 Day 07:nSum 问题

本文详细介绍了如何使用双指针法解决LeetCode中的经典问题,如2sum、3sum和4sum,重点讲解了nSum问题的通用解法,包括排序、双指针移动和处理重复数字的技巧。同时提到了454.四数相加II的HashMap优化方法和383.赎金信的简单解答。
摘要由CSDN通过智能技术生成

今日题目:

今天学习的重点在于 nSum 问题,即如何使用双指针法解决 2sum 问题,然后再基于 2sum 解决 3sum、4sum 问题。

Problem 1:nSum 问题 【必会】

这是 LeetCode 上一个经典的问题,包括 2sum、3sum 以及 4sum 等,解决这类问题的关键是:使用双指针法解决 2sum 问题,基于此,对于 3sum 问题来说,就是固定一个 number 然后转化为 2sum 问题;对于 4sum 问题来说,就是固定一个 number 然后转化为 3sum 问题

nSum 问题的通用解法的讲解可以参考 一个函数秒杀 2Sum 3Sum 4Sum 问题 | labuladong 文章。

理解这个问题有两个关键点

  1. 如何使用双指针法解决 2sum 问题
  2. 如何基于 2sum 解决 3sum 问题

这里有两个易错点(亲身经历):

  1. 一定要先对 nums 进行排序,才能使用双指针法来解

对 nums 排序
2. 指针滑动时,注意跳过重复数字,并且要保证跳跃正确,这里很容易因为一些细节导致小错误

跳过重复数字的逻辑可以写成:

while ( i+1 在合法范围内  &&  nums[i + 1] == nums[i] ) {
    i++;
}
i++;

以上伪代码中,while 循环跳到了重复数字的最后一个,最后一行 i++ 使其跳过了重复数字。注意这里的最后的 i++ 别忘了。

LC 15. 三数之和 【classic, important】

15. 三数之和 | LeetCode

按照前面介绍的,我们需要实现一个 twoSumQuestion() 函数来解决 2sum 问题,然后基于此函数来进一步解决 3sum 问题。其中在解决 2sum 问题时,使用双指针来解决。

所以 Solution 代码的大致框架如下

class Solution {
	private List<List<Integer>> twoSumQuestion(int[] nums, int target, int start, int end) {
		// 双指针法解决 2sum 问题
		return results;
	}
	
	public List<List<Integer>> threeSum(int[] nums) {
		Arrays.sort(nums);  // 对 nums 排序
		
		// ************
		// 基于 2sum 函数解决 3sum 问题
		// ************
		
		return results;
	}
}

我的具体实现代码如下:

class Solution {
    private List<List<Integer>> twoSumQuestion(int[] nums, int target, int start, int end) {
        if (start >= end || start >= nums.length || end > nums.length) {
            return null;
        }
        int left = start, right = end - 1;
        List<List<Integer>> result = new ArrayList<>();
        while (left < right) {
            int sum = nums[left] + nums[right];
            if (sum == target) {
                result.add(List.of(nums[left], nums[right]));
                // left 跳过重复值
                while (left + 1 < right && nums[left + 1] == nums[left]) {
                    left++;
                }
                left++;
                // right 跳过重复值
                while (right - 1 > left && nums[right - 1] == nums[right]) {
                    right--;
                }
                right--;
            } else if (sum < target) {
                left++;
            } else {
                right--;
            }
        }
        return result;
    }

    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> results = new ArrayList<>();
        int i = 0;
        while (i < nums.length - 2) {
            int num = nums[i];
            var twoSumAnswer = twoSumQuestion(nums, 0 - num, i + 1, nums.length);
            twoSumAnswer.forEach(answer -> {
                results.add(List.of(num, answer.get(0), answer.get(1)));
            });
            while (i + 1 < nums.length - 2 && nums[i + 1] == nums[i]) {
                i++;
            }
            i++;
        }
        return results;
    }
}

LC 18. 四数之和 【classic, important】

18. 四数之和 | LeetCode

类比上一个三数之和题目,这个解题思路也是类似,先使用双指针法实现 2sum 问题,基于 2sum 实现 3sum,然后再基于 3sum 实现 4sum 问题。

class Solution {

    private List<List<Integer>> twoSumQuestion(int[] nums, long target, int start, int end) {
        // 使用双指针法实现 2sum 问题
        return results;
    }

    private List<List<Integer>> threeSumQuestion(int[] nums, long target, int start, int end) {
        // 基于 2sum 实现 3sum
        return results;
    }

    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);  // 对 nums 排序
        // 基于 3sum 实现 4sum
        return results;
    }
}

框架是这样,但其中仍存在不少细节,所以还是要亲自多写写。

Problem 2:Other

LC 454. 四数相加 II 【还行】

454. 四数相加 II | LeetCode

这个就和前面的 nSum 不是同一个思路了,主要考察如何使用 HashMap 来降低算法的复杂度,整体略微具有难度。

LC 383. 赎金信 【easy】

题目很容易,直接跳过即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值