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

今日题目:

目录

    • [Problem 1:nSum 问题 【必会】](#Problem 1:nSum 问题 【必会】)
      • [LC 15. 三数之和 【classic, important】](#LC 15. 三数之和 【classic, important】)
      • [LC 18. 四数之和 【classic, important】](#LC 18. 四数之和 【classic, important】)
    • [Problem 2:Other](#Problem 2:Other)
      • [LC 454. 四数相加 II 【还行】](#LC 454. 四数相加 II 【还行】)
      • [LC 383. 赎金信 【easy】](#LC 383. 赎金信 【easy】)

今天学习的重点在于 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 进行排序,才能使用双指针法来解
  1. 指针滑动时,注意跳过重复数字,并且要保证跳跃正确,这里很容易因为一些细节导致小错误

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

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

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

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

15. 三数之和 | LeetCode

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

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

java 复制代码
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;
	}
}

我的具体实现代码如下:

java 复制代码
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 问题。

java 复制代码
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】

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

相关推荐
吃什么芹菜卷2 分钟前
深度学习:词嵌入embedding和Word2Vec
人工智能·算法·机器学习
wclass-zhengge6 分钟前
数据结构与算法篇(树 - 常见术语)
数据结构·算法
labuladuo52011 分钟前
AtCoder Beginner Contest 372 F题(dp)
c++·算法·动态规划
夜雨翦春韭13 分钟前
【代码随想录Day31】贪心算法Part05
java·数据结构·算法·leetcode·贪心算法
hsling松子5 小时前
使用PaddleHub智能生成,献上浓情国庆福
人工智能·算法·机器学习·语言模型·paddlepaddle
dengqingrui1236 小时前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
C++忠实粉丝6 小时前
前缀和(8)_矩阵区域和
数据结构·c++·线性代数·算法·矩阵
ZZZ_O^O6 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
CV-King7 小时前
opencv实战项目(三十):使用傅里叶变换进行图像边缘检测
人工智能·opencv·算法·计算机视觉
代码雕刻家7 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法