三数求和算法

题目

给你一个包含 n 个整数的数组 nums ,判断 nums 中是否存在三个元素 abc ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。( 注意:答案中不可以包含重复的三元组。)

假设:

  • nums[-1, 0, 1, 2, -1, -4]
  • 应返回 [ [-1, 0, 1], [-1, -1, 2] ]

算法优化解析

  1. 所有 求和 的问题都可以转换为 求差
  2. 像这题目普遍做法是三层循环嵌套,但这时间复杂度就是 O(n^3) ,应该考虑用空间换时间,尽可能的少遍历。

像这倒题目:

  • 采取固定最左边的第一个(i),剩下的两个使用 双指针 的方法,一左(j = i+ 1)一右(k = nums.length - 1)
  • 如果 nums[i] + num[j] + nums[k] > 0 ,说明右边指针太大,应向左移(k--),若左移后的值是重复值再向左移。
  • 如果 nums[i] + num[j] + nums[k] < 0 ,说明左边指针大小,应向右移(j++),若右移后的值是重复值再向右移。
  • 如果 nums[i] + num[j] + nums[k] === 0 ,就是这三个,加到结果数组中。

完整代码

const threeSum = (nums) => {
  // 先从小到大排序 nums
  const data = nums.sort((a, b) => a - b)
  // 结果数组
  const res = []
  // 缓存 nums 的长度
  const len = nums.length
  
  // 注意,遍历到倒数第三个就可以了,因为左右指针会遍历后面两个数
  for (let i = 0; i < nums.length - 2; i++) {
    // 左指针
    let j = i + 1
    // 右指针
    let k = len - 1

    // 如果遇到重复的数字,则跳过
    if (i > 0 && nums[i] === nums[i-1]) {
      continue
     }

    while (j < k) {
      // 如果加起来大于 0 ,右指针往左移
      if (data[i] + data[j] + data[k] > 0) {
        k--
        // 如果往左移后值还是相等,继续移动
        while (data[k] === data[k + 1]) {
          k--
        }
      } else if (data[i] + data[j] + data[k] < 0) {
        // 如果加起来小于 0 ,左指针往右移
        j++
        // 如果往右移后值还是相等,继续移动
        while (data[j] === data[j - 1]) {
          j++
        }
      } else {
        // 如果加起来等于 0,得到目标数字组合,推入结果数组
        res.push([data[i], data[j], data[k]])        
        // 左右指针都往中间移动
        j++
        k--

        // 有重复都跳过
        while (data[j] === data[j - 1]) {
          j++
        }
        while (data[k] === data[k + 1]) {
          k--
        }
      }
    }
  }
 return res
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 链表反转 2 链表两两反转 3 判断链表是否有环 3.1 头结点开始遍历,直到位NULL(卡时间,避免死循环...
    289d3a591637阅读 364评论 0 0
  • 题目链接:三数之和 1.题目描述 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a...
    站在海边看远方阅读 308评论 0 0
  • 目录 1 左神部分集锦 2 Leetcode前150题 3 牛客网剑指offer 4 JavaG 5 题目中的...
    小小千千阅读 1,063评论 0 0
  • 整理了校招面试算法题,部分《剑指offer》算法题,以及LeetCode算法题,本博文中算法题均使用Java实现校...
    heyrenly阅读 802评论 0 4
  • 简述 极客时间算法40讲中所出现的leetcode算法题 题目 【链表】reverse-linked-list(反...
    BestbpF阅读 4,498评论 0 4