LeetCode Everyday - 四数之和

74 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n a、b、c 和 d 互不相同 nums[a] + nums[b] + nums[c] + nums[d] == target 你可以按 任意顺序 返回答案 。

示例1:

输入: nums = [1,0,-1,0,-2,2], target = 0
输出: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

示例2:

输入: nums = [2,2,2,2,2], target = 8
输出: [[2,2,2,2]]

提示:

  • 1 <= nums.length <= 200
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109

解题思路:

1. 对原数组进行排序
2. 最外层循环,直到 nums.lengt -3,确定 j 指针。
3. 内层循环,直到 nums.length - 2, 确定 j 指针。
4. 接下来,利用 k, l 双指针在 nums 数组上面移动,寻找等于 target 的组合,同时为了去重,将组合的字符串形式保存为 cache。直到 k === l。
5. 如果 当前 sum value 大于等于 target, 向左移动 l 指针,否则,向右移动 k 指针。

我的答案:

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[][]}
 */
var fourSum = function(nums, target) {
    const size = nums.length
    let results = []

    if (size < 4) {
        return []
    }

    // Sort nums.
    nums.sort((a, b) => a - b)

    const max = size - 1
    let j, k, l = 0
    const cache = {}

    for (let i = 0; i < size-3; i++) {
        for (let j = i+1; j < size-2; j++) {
            k = j+1
            l = max

            // Jump out loop when k pointer meets l pointer, which means all elements iterated.
            while (k !== l) {
                const digits = [nums[i], nums[j], nums[k], nums[l]]
                const sum = digits.reduce((accum, currnet) => accum + currnet, 0)
                const sumStr = digits.join('')

                if (sum === target) {
                    // Convert digits array to be string, cache it as key of `cache` map.
                    if (cache[sumStr] === undefined) {
                        cache[sumStr] = 1 // Cache new result
                        results.push(digits) // Add new result
                    }
                }

                if (sum < target) { // If current sum value too small, right move k pointer.
                    k++
                } else { // Others, if current sum equals to target of bigger, left move l pointer.
                    l--
                }
            }
        }
    }

    return results
};

最后

如果有更好的解法或者思路, 欢迎在评论区和我交流~ ღ( ´・ᴗ・` )