双指针(简化哈希)力扣15.三数之和

题目

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != 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 。

示例 3:

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

提示:

  • 3 <= nums.length <= 3000
  • -10^5 <= nums[i] <= 10^5

思路 

本题与四数之和Ⅱ的区别在于,本题得到的结果需要去重,如果用哈希法,去重将会十分困难并且很难做到bug free,因此我们采用双指针法来进行简化的去重和结果的实现,详细的去重细节请看下面的代码所描述的,认真观察和思考去重,是本题的一大重点。

代码实现

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>>result;//用于存储结果
        int i,left,right;
        sort(nums.begin(),nums.end());
        //对数组进行排序,好处有两个
        //1.方便我们使用双指针不断移动,向中间靠拢 2.如果发现第一位是大于0的数那么就及时终止
        for(i=0;i<nums.size();i++){
            if(nums[i]>0)return result;//如果发现i也就是第一位大于0
                                       //后面加和也一定不可能等于0,故及时终止
            if(i>0&&nums[i]==nums[i-1])//对第一位进行去重,这里一定要是后一位和前一位相比
            //因为如果前一位和后一位相比的话会导致重复元素无法计数,后一位比前一位,这样可以
            //刚好越过重复元素,避免-1 -1 2情况
                continue;
            left=i+1;//设置初始第二个值,也就是双指针左端
            right=nums.size()-1;//设置初始第三个值,也就是双指针右端
            while(left<right){//因为如果双指针相等,那么就重复了同一个数字,不能让其相等
                if(nums[i]+nums[left]+nums[right]<0)left++;
                //如果和小于0,那么说明和过小,让左端向右移动,也就是变大
                else if(nums[i]+nums[left]+nums[right]>0)right--;
                //如果和大于0,那么说明和过大,让右端向左移动,也就是变小
                //这样做刚好可以遍历所有值
                else{
                    result.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    //如果发现所需值,就让其插入结果集
                    while(left<right&&nums[left+1]==nums[left])left++;
                    //对第二个数进行去重,如果一直相等一直右移
                    while(left<right&&nums[right]==nums[right-1])right--;
                    //对第三个数进行去重,如果一直相等一直左移
               //如果该去重放在一开始,那么0 0 0 情况就会被省略,因此我们至少找到一组再去重
                    left++;
                    right--;
                    //找到一组就相对收缩一次,和前面的去重不矛盾,因为去重一直去的是相同值
                };
            }
        }
        return result;//返回结果集
    }
};

关键点:去重

①对第一个数去重

if(i>0&&nums[i]==nums[i-1])//对第一位进行去重,这里一定要是后一位和前一位相比
            //因为如果前一位和后一位相比的话会导致重复元素无法计数,后一位比前一位,这样可以
            //刚好越过重复元素,避免-1 -1 2情况
    continue;

②对第二个数去重

while(left<right&&nums[left+1]==nums[left])left++;
                    //对第二个数进行去重,如果一直相等一直右移

③对第三个数去重

 while(left<right&&nums[right]==nums[right-1])right--;
                    //对第三个数进行去重,如果一直相等一直左移

④去重位置和逻辑

1.对于第一个数的去重,我们要考虑是后一位和前一位相比进行去重,否则会导致,结果集缺失存在相同元素,类似于-1 -1 2的结果集。

2.对于第二第三个数的去重,我们要考虑的是去重的位置,如果过于提前,那么可能导致结果集缺失或者为空的结果集,类似于0 0 0的结果集。

总结

这道题简化了哈希算法,采用了双指针,虽然时间复杂度也不低,但是为我们提供了新的思路和思考,对bug free降低了要求,做好本题主要在于对关键点的把握和关注,如果把握好了去重的逻辑和位置,以及去重的细节和理解,那么相信做对这道题对你来说就是易如反掌。

尾声

本题通过复杂的去重和剪枝,告诉我们哈希算法的不利情况和相应的代替算法,希望大家通过本题对双指针和哈希表的认识和理解进一步加深,如果觉得笔者写的还不错的话,记得留下您的点赞,关注和收藏,和作者一起学习算法呀~

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

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

相关文章

ADS仿真 之 瞬态仿真

瞬态仿真常用于低频模拟和数字电路的仿真&#xff0c;是用来模拟电压或者电流随时间的变化趋势&#xff0c; ADS在Simulation-transient面板中提供了与瞬态仿真相关的控件&#xff0c; 主要是瞬态仿真控件&#xff0c;一般的瞬态仿真主要关注时间的设置和时间的控制方式&#x…

编码技巧(二) element-ui table中根据状态控制是否可以勾选

项目中使用element-ui时,表格中的数据有不同的状态,需要对某个状态的数据进行 勾选操作 如图所示: 只有id为12的符合条件可以进行勾选 <el-table-column type="selection" header-align="center" :selectable="selectable" align="c…

1.4.1机器学习——梯度下降+α学习率大小判定

1.4.1梯度下降 4.1、梯度下降的概念 ※【总结一句话】&#xff1a;系统通过自动的调节参数w和b的值&#xff0c;得到最小的损失函数值J。 如下&#xff1a;是梯度下降的概念图。 我们有一个损失函数 J(w,b)&#xff0c;包含两个参数w和b&#xff08;你可以想象成J(w,b) w*x…

竞赛保研 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

GCF:在线市场异质治疗效果估计的广义因果森林

英文题目&#xff1a;GCF: Generalized Causal Forest for Heterogeneous Treatment Effects Estimation in Online Marketplace 中文题目&#xff1a;GCF&#xff1a;在线市场异质治疗效果估计的广义因果森林 单位&#xff1a;滴滴&美团 时间&#xff1a;2022 论文链接…

postgresql迁移到mysql

1.工具方法&#xff1a;Navicat Premium16 2. 手工方法&#xff1a; 迁移流程 下面是将 Postgresql 数据库迁移到 MySQL 的步骤流程&#xff1a; 步骤描述1. 创建MySQL表结构在MySQL中创建与Postgresql中的表结构相同的表2. 导出Postgresql数据将Postgresql中的数据导出为SQ…

【学术会议】第三届神经计算青年研讨会 学习笔记

第三届神经计算青年研讨会 学习笔记 会议时间&#xff1a;2024-1-6至2024-1-7 会议地点&#xff1a;电子科技大学 会议介绍&#xff1a; 为提升我国神经计算⻘年研究队伍的学术⽔平和国际影响⼒&#xff0c;研讨会主题涵盖&#xff1a;神经系统建模与模拟、脑机接⼝与类脑智能、…

Rabbitmq 消息可靠性保证

1、简介 消息的可靠性投递就是要保证消息投递过程中每一个环节都要成功&#xff0c;本文详细介绍两个环节的消息可靠性传递方式&#xff1a;1&#xff09;、消息传递到交换机的 confirm 模式&#xff1b;2&#xff09;、消息传递到队列的 Return 模式。 消息从 producer 到 ex…

SD-WAN跨境专线:优化企业网络效率与安全性

企业网络通信的革新已经成为跨境业务发展中的重要一环。新加坡作为国际商业中心&#xff0c;吸引着众多企业在此开设分支机构。然而&#xff0c;传统的跨境网络连接方式常常存在着诸多问题&#xff0c;例如网络延迟高、丢包率大等。在这些挑战面前&#xff0c;SD-WAN&#xff0…

【leetcode】力扣算法之两数相加【中等难度】

题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都…

助力企业出海,Ogcloud提供一站式网络解决方案

随着全球市场的开放和跨境电商的蓬勃发展&#xff0c;越来越多企业开始在海外拓展业务。但在这过程中&#xff0c;各种各样的网络问题成为企业出海的阻碍。Ogcloud凭借其卓越的技术实力和丰富的经验&#xff0c;为全球业务的公司提供全面的网络解决方案&#xff0c;包括SD-WAN、…

C语言如何提高程序的可读性?

一、问题 可读性是评价程序质量的一个重要标准&#xff0c;直接影响到程序的修改和后期维护&#xff0c;那么如何提高程序的可读性呢? 二、解答 提高程序可读性可以从以下几方面来进行。 &#xff08;1&#xff09;C程序整体由函数构成的。 程序中&#xff0c;main()就是其中…

C#,数值计算,高斯消元法与列主元消元法的源代码及数据动态可视化

高斯消元法&#xff01; 一、高斯消元法 Gaussian Elimination 高斯消元法&#xff08;或译&#xff1a;高斯消去法&#xff09;&#xff0c;是线性代数中的一个常用算法&#xff0c;常用于求解线性方程组和矩阵的逆。 本程序的运行效果&#xff1a; 1、高斯消元法的动画演示…

Linux学习19 在Ubuntu命令行下使用新硬盘

Linux学习19 在Ubuntu命令行下使用新硬盘 一、准备环境二、检测硬盘三、对新硬盘格式化1. 创建分区2. 格式化 三、挂载操作1. 创建挂载点2. 挂载硬盘3. 验证挂载 四、实现永久挂载&#xff08;可选&#xff09;1. 文件结构与内容&#xff1a;2. /etc/fstab 的重要性与作用3. 修…

运算符详解

1、定义 定义&#xff1a;运算符是一种特殊的符号&#xff0c;用于表示数据的运算、赋值和比较等 运算符的分类 1&#xff09;按功能分类&#xff1a; 1&#xff09;算术运算符&#xff08;7个&#xff09;​​​​​​​ 、-、*、/、%、、--​​​​​​​ 2&#xff0…

自动化测试框架pytest系列之基础概念介绍(一)

如果你要打算学习自动化测试 &#xff0c;无论是web自动化、app自动化还是接口自动化 &#xff0c;在学习的道路上&#xff0c;你几乎会遇到pytest这个测试框架&#xff0c;因为自动化编写没有测试框架&#xff0c;根本玩不了 。 如果你已经是一位自动化测试人员 &#xff0c;…

工程监测领域振弦采集仪的数据处理与分析方法探讨

工程监测领域振弦采集仪的数据处理与分析方法探讨 在工程监测领域&#xff0c;振弦采集仪是常用的一种设备&#xff0c;用于测量和记录结构物的振动数据。数据处理和分析是使用振弦采集仪得到的数据的重要环节&#xff0c;可以帮助工程师了解结构物的振动特性&#xff0c;评估…

FRPS配置服务端(腾讯云)、客户端(PC电脑Windows、树莓派Debian)并设置虚拟域名

1.服务端&#xff08;腾讯云&#xff09;&#xff1a;frps.ini [common] bind_port 7000 vhost_http_port8080 vhost_https_port44344 dashboard_port 7500 privilege_token your_password subdomain_host example.com use_encryption true encryption_method tls dashb…

面试宝典进阶之关系型数据库面试题

D1、【初级】你都使用过哪些数据库&#xff1f; &#xff08;1&#xff09;MySQL&#xff1a;开源数据库&#xff0c;被Oracle公司收购 &#xff08;2&#xff09;Oracle&#xff1a;Oracle公司 &#xff08;3&#xff09;SQL Server&#xff1a;微软公司 &#xff08;4&#…

RabbitMQ发布确认

1.单个确认 单个确认发布是一种同步确认发布方式&#xff0c;也就是发布一个消息后只有它被确认发布&#xff0c;后续的消息才能继续发布。 缺点:发布速度特别慢,因为若是没有确认发布的消息会阻塞所有后续消息的发布 package com.hong.rabbitmq5;import com.hong.utils.Rabb…