hgq's docs
主页
ES6-阮一峰 (opens new window)
Vue文档 (opens new window)
Axios文档 (opens new window)
Vue Router (opens new window)
Vuex文档 (opens new window)
面试题-Vue (opens new window)
面试题-JS (opens new window)

guoguoqiqi

漫不经心的向往
主页
ES6-阮一峰 (opens new window)
Vue文档 (opens new window)
Axios文档 (opens new window)
Vue Router (opens new window)
Vuex文档 (opens new window)
面试题-Vue (opens new window)
面试题-JS (opens new window)
  • 反转链表
  • 无重复字符的最长子串
  • LRU 缓存
  • 数组中的第K个最大元素
  • K个一组翻转链表
  • 三数之和
    • 手撕快速排序
    • 最大子数组和
    • 两数之和
    • 合并两个有序链表
    • 环形链表
    • 二叉树的层序遍历
    • 买卖股票的最佳时机
    • 二叉树的锯齿形层序遍历
    • 相交链表
    • 有效的括号
    • 二叉树的最近公共祖先
    • 合并两个有序数组
    • 搜索旋转排序数组
    • 最长回文子串
    • 岛屿的数量
    • 全排列
    • 字符串相加
    • 高频算法题
    guoguoqiqi
    2022-03-17

    三数之和

    给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

    注意:答案中不可以包含重复的三元组。

    示例 1:

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

    # 解法:双指针

    思路:

    外层循环:指针 i 遍历数组。 内层循环:用双指针,去寻找满足三数之和 == 0 的元素

    先排序的意义 便于跳过重复元素,如果当前元素和前一个元素相同,跳过。

    双指针的移动时,避免出现重复解 找到一个解后,左右指针同时向内收缩,为了避免指向重复的元素,需要:

    • 左指针在保证left < right的前提下,一直右移,直到指向不重复的元素
    • 右指针在保证left < right的前提下,一直左移,直到指向不重复的元素

    小优化 排序后,如果外层遍历的数已经大于0,则另外两个数一定大于0,sum不会等于0,直接break。

    const threeSum = (nums) => {
      nums.sort((a, b) => a - b); // 排序
    
      const res = [];
    
      for (let i = 0; i < nums.length - 2; i++) { // 外层遍历
        let n1 = nums[i];
        if (n1 > 0) break; // 如果已经爆0,不用做了,break
        if (i - 1 >= 0 && n1 == nums[i - 1]) continue; // 遍历到重复的数,跳过    
    
        let left = i + 1;            // 左指针
        let right = nums.length - 1; // 右指针
    
        while (left < right) {
          let n2 = nums[left], n3 = nums[right];
    
          if (n1 + n2 + n3 === 0) {  // 三数和=0,加入解集res
            res.push([n1, n2, n3]);
            while (left < right && nums[left] == n2) left++; // 直到指向不一样的数
            while (left < right && nums[right] == n3) right--; // 直到指向不一样的数
          } else if (n1 + n2 + n3 < 0) { // 三数和小于0,则左指针右移
            left++;
          } else {      // 三数和大于0,则右指针左移
            right--;
          }
        }
      }
      return res;
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/3sum

    ← K个一组翻转链表 手撕快速排序→

    最近更新
    01
    vuex数据持久化怎么做
    05-22
    02
    vue的动态路由怎么配置使用
    05-22
    03
    vue权限控制一般怎么做
    05-22
    更多文章>
    Theme by Vdoing | Copyright © 2022-2022 Guoquoqiqi | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式