IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode 15. 三数之和 -> 正文阅读

[数据结构与算法]LeetCode 15. 三数之和

15. 三数之和

题目描述

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

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

在这里插入图片描述

解题思路

思路一: 排序 + 双指针

本题的难点在于如何去除重复解。
为了解决这个问题, 我们可以将数组进行排序, 当nums[i] === nums[i - 1]时, 此时将nums[i]作为第一个数与nums[i - 1]作为第一个数得到的满足条件的三元组是一致的, 所以此时nums[i]我们就不再进行判断, 此时就可以避免出现重复解,当然对于第二个数、第三个数判断条件也是一样。

算法流程:

  1. 对数组进行排序;
  2. 遍历排序后数组:
    • 若 nums[i]>0:因为已经排序好,所以后面不可能有三个数和等于 0,直接返回结果。
    • 对于重复元素:跳过,避免出现重复解
    • 令left = i + 1, right = nums.length - 1, 此时判断nums[i] + nums[left] + nums[right] 结果等于0即可; 当 left < right 时,执行循环:
      • 当和等于0,则加入结果集并执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 left 右移 right 左移,寻找新的解
      • 若和大于 0,说明 nums[right] 太大,right 左移
      • 若和小于 0,说明 nums[left] 太小,left 右移

实现代码如下:

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function(nums) {
    let result = [], 
        len = nums.length,
        left, 
        right;
    // 先进行排序
    nums.sort((a, b) => a - b);
    for (let i = 0; i < len; i++) {
        let curr = nums[i];
        // 第一个数大于 0,后面的数都比它大,肯定不成立
        if (curr > 0) break;
        // 对第一个数去重
        if (i > 0 && curr === nums[i - 1]) continue;

        left = i + 1; 
        right = len - 1;
        while(left < right) {
            const sum = curr + nums[left] + nums[right];
            if (!sum) {
                result.push([curr , nums[left] , nums[right]]);
                // 接着去重
                while(left < right && nums[left] === nums[left + 1]) left++;
                while(left < right && nums[right] === nums[right - 1]) right--; 
                left++;
                right--; 
            } else if (sum < 0) {
                left++;
            } else if (sum > 0) {
                right--; 
            } 

        }
    }
    return result;
};
  • 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n 是数组 nums 的长度。数组排序 O ( n l o g n ) O(nlogn) O(nlogn),遍历数组 O ( n ) O(n) O(n),双指针遍历 O ( n ) O(n) O(n),总体 O ( n l o g n ) + O ( n ) ? O ( n ) O(nlogn)+O(n)?O(n) O(nlogn)+O(n)?O(n),即 O ( n 2 ) O(n^2) O(n2)

  • 空间复杂度: O ( l o g n ) O(logn) O(logn)

参考资料

排序 + 双指针,逐行解释 - 三数之和 - 力扣(LeetCode)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:39:02  更:2022-10-22 21:39:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:14:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码