前端算法面试必刷题系列[5]

264 阅读2分钟

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

11. 四数之和 (4sum)

标签

  • 排序
  • 双指针
  • 中等

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给定一个数组,要求在这个数组中找出 4 个数之和为 0 的所有组合。本题的难点在于如何去除重复解。跟三数只和基本一样思路。

基本思路

三数之和基本一模一样,唯一不一样的是三数中间定了一个 i,4数需要两个 for 来定两位组合。

写法实现

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[][]}
 */
var fourSum = function(nums, target) {
  let [res, len, first, second, left, right, sum] = [[], nums.length, 0, 0, 0, 0, 0]
  // 特判
  if (len < 4) {
      return []
  }
  // 先排序
  nums = nums.sort((a, b) => a - b)
  // 前面两个指针,第一个从 0 ~len-3(第一个指针,后面数不够了至少要4个)
  // 第二个是跟在第一个之后 所以是 first + 1
  for (first = 0; first < len - 3; first++) {
    if (first > 0 && nums[first] === nums[first-1]) {
      continue
    }
    for(second = first + 1; second < len - 2; second++) {
      if (second > first+1 && nums[second] === nums[second-1]) {
        continue;
      }
      // 临时变量记录前两个选定数的和
      let tempSum = nums[first] + nums[second]
      // 再用双指针来处理
      left = second + 1
      right = len - 1
      while (left < right) {
        sum = tempSum + nums[left] + nums[right]
        // 和等于 0 满足条件 进结果数组
        if (sum === target) {
          res.push([nums[first], nums[second], nums[left], nums[right]])
          // 判断左界和右界是否和下一位置重复,去除重复解。
          while (left < right && nums[left] === nums[left+1]) {
            left++
          }
          while (left < right && nums[right] === nums[right-1]) {
            right--
          }
          // 并同时将 left,right 移到下一位置,寻找新的解
          left++
          right--
        } else if (sum > target) {
          // 和大于 0 的情况,说明 nums[right] 太大,right 左移
          right--
        } else {
          left++
        }
      }
    }
  }
  return res
};

let nums = [-2,-1,-1,1,1,2,2], target = 0
console.log(fourSum(nums, target))

年初一就来一题吧。

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the reiver monster,我看到就通过,暗号对不上不加哈