Leetcode的AC指南 —— 哈希法/双指针:15. 三数之和

摘要:
Leetcode的AC指南 —— 15. 三数之和。题目介绍:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请 你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。

文章目录

  • 一、题目
  • 二、解析
    • 1、哈希法
    • 2、双指针
  • 3、思考

一、题目


题目介绍
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请 你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。
力扣题目链接

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1][-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0

示例 2:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0

提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105

二、解析


1、哈希法

public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums); // 对数组排序

        // 找出a + b + c = 0
        // a = nums[i], b = nums[j], c = -(a + b)

        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) {
                break;
            }
            // 对a去重
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            Set<Integer> set = new HashSet<>();
            for (int j = i + 1; j < nums.length; j++) {
                // 对b去重, 由于存在b == c,所以在对b去重时,排除nums = [-1,-1,0,1,-4,0,2,2,2,2]这种情况,避免出现两次【-4,2,2】
                if (j > i + 2 && nums[j] == nums[j - 1] && nums[j - 1] == nums[j - 2]) {
                    continue;
                }

                // 如果set中存在c,则将a,b,c存入result
                // 如果set中不存在c,添加c到set
                int c =  - (nums[i] + nums[j]);
                if (set.contains(c)) {
                    result.add(Arrays.asList(nums[i], nums[j], c));
                    set.remove(c); // 对c去重复
                } else {
                    set.add(nums[j]);
                }
            }
        }
        return result;

    }

  • 时间复杂度: O(n^2)
  • 空间复杂度: O(n),额外的 set 开销

2、双指针

动画效果如下:
在这里插入图片描述

public static List<List<Integer>> threeSum(int[] nums) {

        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums); // 对数组排序
        int right, left;
        // a + b + c = 0
        for(int i = 0; i < nums.length - 2; i++){

            if(nums[i] > 0 || nums[nums.length - 1] < 0) break; // 最小值大于0,最大值小于0时,不满足题意,直接跳出循环
            if(i > 0 && nums[i] == nums[i - 1]) continue; // 对a去重复

            left = i + 1; // 左指针指向a后的第一个元素
            right = nums.length - 1; // 右指针指向数组的最后一个元素

            while (left < right) {

                int sum = nums[i] + nums[left] + nums[right];

                if (sum > 0) {
                    right--;
                } else if (sum < 0) {
                    left++;
                } else {
                    result.add(Arrays.asList(nums[i], nums[left], nums[right]));
                    // 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
                    while (right > left && nums[right] == nums[right - 1]) right--; // 左移指针,指向第一个相邻不重复的元素右侧
                    while (right > left && nums[left] == nums[left + 1]) left++; // 右移指针,指向第一个相邻不重复的元素的左侧
                    right--; // 右指针指向第一个相邻不重复的元素
                    left++; // 左指针指向第一个相邻不重复的元素
                    /*
                    while (right > left) {
                        right--;
                        if(nums[right] != nums[right + 1]) break;
                    } // 左移指针,指向第一个相邻不重复的元素
                    while (right > left && nums[left] == nums[left - 1]) left++; // 右移指针,指向第一个相邻不重复的元素
                     */

                }
            }
        }

        return result;
    }
  • 时间复杂度: O(n^2)
  • 空间复杂度: O(1)

3、思考


两数之和可以用双指针法吗?两数之和的题目链接

答: 是不可以的。两数之和要求返回数组索引下标,而双指针法要求排序,一旦排序后,原数组的索引下标就改变了。如果两数之和也是返回数值的话,就可以使用双指针了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/279533.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构学习 Leetcode72 编辑距离

关键词&#xff1a;动态规划 最长公共子序列 题目&#xff1a; 思路&#xff1a; 这题我虽然做出来了但是还是有点迷糊。首先&#xff0c;这道题一定是和最长公共子序列相似的。 所以往最长公共子序列方向思考&#xff0c;考虑的它的状态和转移方程以及边界。 状态和转移方…

Ajax学习

文章目录 AjaxAjax 是什么Ajax 经典应用场景Ajax 原理示意图ajax的异步请求的方法ajax的逻辑:应用实例-验证用户名是否存在思路框架图:需求分析: 到数据库去验证用户名是否可用思路框架图大功告成:使用JQuery-Ajax实现上面相同的需求:Ajax Ajax 是什么 AJAX 即"Async…

【HTML5】第1章 HTML5入门

学习目标 了解网页基本概念&#xff0c;能够说出网页的构成以及网页相关名词的含义 熟悉Web标准&#xff0c;能够归纳Web标准的构成。 了解浏览器&#xff0c;能够说出各主流浏览器的特点。 了解HTML5技术&#xff0c;能够知道HTML5发展历程、优势以及浏览器对HTML5的支持情…

【嵌入式开发学习必备专栏】

文章目录 嵌入式开发学习必备专栏1.1 ARM Coresight SoC-400/SoC-600 专栏导读目录1.1.1 Performance Profiling1.1.2 ARM Coresight Debug 工具系列1.1.2.1 ARM DS5 系列1.1.2.2 劳特巴赫 Trace32 系列1.1.2.3 JTAG OpenOCD 系列 1.2 ARM Cache 专栏1.3 ARM AMBA Bus 专栏1.3.…

java使用JSON工具解析字符串、数组详解

一&#xff1a;问题 1.最近自己在前后端数据交互时需要进行JSON格式字符串、数组数据进行转换&#xff0c;进行问题整理 2.遇到需要JSON字符串转换的朋友可以阅读 二&#xff1a;解析步骤 1.第一点首先确定需求&#xff0c;明确需要转的字符串是一个对象还是一个数组&#…

C练习——判断三角形并求面积

题目&#xff1a;从健盘任意输入三角形的三边长为a,b,c,编程判断a,b,c的值能否构成一个三角形&#xff0c;若能构成三角形&#xff0c;则计算并输出三角形的面积&#xff0c;否则提示不能构成三角形。 已知构成三角形的条件是&#xff1a;任意两边之和大于第三边。 解析&#…

jQuery-Validate验证插件的使用步骤【详解】

jQuery-Validate验证插件的使用步骤详解 1. 写在前面2. 效果展示3. Validate环境的搭建4. Validate基本方法的使用5. 实现错误消息的本地化6. 实现远程验证7. 自定义验证方法8. 验证表单完整版8.1 Html表单8.2 表单验证js逻辑8.3 表单验证css样式 1. 写在前面 我们知道&#x…

windows11经常断网WiFi

解决方法&#xff1a;从官方网站下载&#xff0c;更新WiFi驱动程序&#xff0c;

Linux:apache优化(2)—— 网页传输压缩

网页传输压缩 客户端在请求httpd服务器数据&#xff0c;httpd服务器在返回数据包给客户端时&#xff0c;先对返回的数据进行压缩&#xff0c;压缩之后再传输 作用&#xff1a;配置 Apache 的网页压缩功能&#xff0c;是使用 Gzip 压缩算法来对 Apache 服务器发布的网页内容进行…

AI又进化了,AI 写代码工具

今年 AI 的发展可谓一日千里&#xff0c;相信不少同学应该都用过 AI 来帮助自己提高开发效率吧&#xff1f; 比如让 AI 根据注释生成代码、解释整段代码、提供技术问题的答疑、修改 Bug、生成单元测试等等。 在 12 月 28 日刚刚结束的 WAVE SUMMIT 深度学习开发者大会上&…

STM32CubeMX教程8 TIM 通用定时器 - 输出比较

目录 1、准备材料 2、实验目标 3、实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.1、外设初始化函数调用流程 3.2.2、外设中断函数调用流程 3.2.3、添加其他必要代码 4、常用函数 5…

Mysql 容易忘的 sql 指令总结

目录 一、操作数据库的基本指令 二、查询语句的指令 1、基本查询语句 2、模糊查询 3、分支查询 4、 分组查询 5、分组查询 6、基本查询总结&#xff1a; 7、子查询 8、连接查询 三、MySQL中的常用函数 1、时间函数 2、字符串函数 3、聚合函数 4、运算函数 四、表…

Leetcode 63 不同路径 II

题意理解&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 要求&#xff1a;机器人只能…

Jmeter学习总结(4)——提取接口响应内容JSON Extractor

后置提取常见的方式&#xff1a;正则表达式和JSON Extractor。 而接口响应大多是JSON格式。 在JSON提取器之前&#xff0c;可以根据响应结果去编写所需要的JSON表达式&#xff0c;在结果树中选择JSON PATH TESTER。 {"server_time": 1232333333333,"data&quo…

基于ssm的4S店预约保养系统开发+vue论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

双语!性能优越|融合黏菌和差分变异的量子哈里斯鹰算法SDMQHHO

前面的文章里卡卡介绍了哈里斯鹰优化算法(Harris Hawks Optimization, HHO).HHO是 Heidari等[1]于2019年提出的一种新型元启发式算法&#xff0c;设计灵感来源于哈里斯鹰在捕食猎物过程中的合作行为以及突然袭击的狩猎风格&#xff0c;具有需调参数少、原理简单易实现、局部搜索…

Spring AOP<一>简介与基础使用

spring AOP 基础定义 含义使用切面组织多个Advice,Advice放在切面中定义。也就是说是定义通知的自定义类。自定义的AOP类Aspect连接点方法调用&#xff0c;异常抛出可以增强的点JoinPoint &#xff1a;也就是**被增强的方法的总称&#xff0c;可以获取具体方法的信息&#xff…

(2023,3D NeRF,无图像变分分数蒸馏,单步扩散)SwiftBrush:具有变分分数蒸馏的一步文本到图像扩散模型

SwiftBrush : One-Step Text-to-Image Diffusion Model with Variational Score Distillation 公众&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要 1. 方法 1.1 基础 1.2 SwiftBrus…

图像分割实战-系列教程2:Unet系列算法

图像分割实战-系列教程 总目录 语义分割与实例分割概述 Unet系列算法 1、Unet 整体结构&#xff1a;概述就是编码解码过程简单但是很实用&#xff0c;应用广起初是做医学方向&#xff0c;现在也是 语义分割与实例分割概述 Unet系列算法

MYSQL 深入探索系列六 SQL执行计划

概述 好久不见了&#xff0c;近期一直在忙项目的事&#xff0c;才有时间写博客&#xff0c;近期频繁出现sql问题&#xff0c;今天正好不忙咱们看看千万级别的表到底该如何优化sql。 案例 近期有个小伙伴生产环境收到了告警&#xff0c;有个6千万的日志表&#xff0c;查询耗时大…