73、【哈希表】leetcode——15. 三数之和(C++版本)

news2024/9/24 17:18:30

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原题链接:15. 三数之和

解题思路

本题的难点在于去重,针对两种不同的方式:双指针和Hash采用不同的去重判定条件。

1、去重的目标

要明确,去重的是重复三元组,而不是三元组里重复的数。

2、去重初步思路

为了方便去重,第一步是先排序,可保证 nums[i]≤nums[j]≤nums[k] 。当按次顺序从前往后依次遍历时,不会出现因异位而出现的重复三元组,例如[1,1,2][1,2,1]。而可能会出现因数组中本身存在的相同元素导致出现记录重复三元组,例如[0,0,0][-1,-1,2]等。

因此我们的目标便是:对于含有重复元素的数,每次仅对比记录一次,若后续再次出现重复元素,则将其跳过。

一、排序+双指针法

1、双指针思路

双指针的思路是从前往后,确定第一个元素nums[i]后,再在该元素的后续集合中的首和尾分别设置指针lr。利用数组元素中的单调性,找到nums[i] + nums[l] + nums[r] == 0时的三个数。

(1)若nums[i] + nums[l] + nums[r] < 0,说明三者相加的数小了,l++

(2)若nums[i] + nums[l] + nums[r] > 0,说明三者相加的数大了,r--

(3)若nums[i] + nums[l] + nums[r] == 0,则找到目标数,记录到结果集res中。

2、去重思路

  1. 对于第一个元素nums[i],为了保证第一次出现的重复元素被记录并且还不会记录后续重复元素,去重条件设为 nums[i] == nums[i - 1],当满足该条件时,认为有重复元素,应跳过本次遍历,执行continue
  2. 对于第二个元素nums[l],我们会在之前就将第一次出现并满足三者相加等于0的元素,加入到结果集res中。因此,去重条件为nums[l] == nums[l + 1],确保后续重复元素不再被记录。
  3. 对于第三个元素nums[k],理由同上,去重条件为nums[r] == nums[r - 1],确保后续重复元素不再被记录。
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());     // 先排序
        for(int i = 0; i < n - 2; i++) {    // 对i从0~n-2,留出两个位置用作l和r
            if(nums[i] > 0)     break;      // 当遍历的第一个数大于0,则后续相加的两个数一定不会为0
            if(i > 0 && nums[i] == nums[i - 1])     continue;   // 去重。与i-1相比,若之前i已有相等数加入其中,则次数若再加入,则会出现重复三元组。不和i+1进行比较的原因是避免出现漏记元素
            int l = i + 1, r = n - 1;       // 双指针分别从i后的首和尾开始遍历
            while(l < r) {
                while(l < r && nums[i] + nums[l] + nums[r] < 0)     l++;    // 比0小,说明需要增大,l++
                while(l < r && nums[i] + nums[l] + nums[r] > 0)     r--;    // 比0大,说明需要减小,r--
                if(l < r && nums[i] + nums[l] + nums[r] == 0) {             // 找到相加等于0时
                    res.push_back(vector<int>{ nums[i], nums[l], nums[r]}); // 先将目标结果加入其中
                    while(l < r && nums[l] == nums[l + 1])      l++;        // 去重。因已有nums[l]加入结果中,如果下一个数与之相等,那么会出现重复三元组
                    while(l < r && nums[r] == nums[r - 1])      r--;        // 理由同上
                    l++, r--;                                               // 上述while只是保证了后续不出现重复元素,还需要更新指针的值,指向后续元素
                }
            }
        }
        return res;
    }
};

时间复杂度 O ( n 2 ) O(n^2) O(n2)
空间复杂度 O ( l o g n ) O(log n) O(logn) (忽略存储答案的空间,额外的排序的空间复杂度为 O ( l o g n ) O(log n) O(logn)

二、排序+hash表法(不方便)

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());     // 先对元素排序
        for(int i = 0; i < n; i++) {
            if(nums[i] > 0)     break;      // 如果起始遍历的元素大于0,那么后续的元素再相加一定不会为0
            if(i > 0 && nums[i] == nums[i - 1])     continue;   // 去重nums[i]
            unordered_set<int> record;
            for(int j = i + 1; j < n; j++) {
                // 去重nums[j]
                if(j > i + 2 && nums[j] == nums[j - 1] && nums[j - 1] == nums[j - 2])
                    continue;
                int gap = 0 - (nums[i] + nums[j]);      // 找到相加为0的nums[k]
                if(record.find(gap) != record.end()) {
                    res.push_back({ nums[i], nums[j], gap});
                    record.erase(gap);      // 去重nums[k]
                } else {
                    record.insert(nums[j]);
                }
            }
        }
        return res;
    }
};

参考文章: 第15题. 三数之和、三数之和

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

商业与数据生态议题解读,Doris Summit 2022 分论坛议程介绍|即刻报名

Doris Summit 2022 将于1 月 6 -7 日在线上正式举办&#xff0c;本次峰会共分2 天进行&#xff0c;首日上午为主论坛&#xff1a;核心技术解析&#xff0c;下午为商业与数据生态分论坛&#xff0c;7 日全天为行业用户最佳实践案例。大会汇聚了来自全球顶尖云厂商、一线互联网企…

CoMER论文翻译

文章目录Abstract1、Introduction2、Related Work2.1 HMER Methods2.2 Coverage Mechanism3、Methodology3.1、Background3.2、CNN Encoder3.3、Positional Encoding3.4、Attention Refinement Module3.5、Coverage4 Experiments论文链接&#xff1a;https://arxiv.org/abs/220…

数字图像处理 图像对比度增强算法概览

一、图像对比度增强 图像对比度增强又叫作图像对比度拉伸或者直接称为点运算。图像亮度和对比度调整的目的之一是在合适的亮度上提供最大的细节信息&#xff0c;细节纹理的沟纹越深&#xff0c;图像越清晰。在图像处理中&#xff0c;图像对比度增强是最基本的、原理比较简单却很…

【前端】Vuex模块化和持久化应用示例

概述 Vuex作为VUE状态管理组件&#xff0c;能够将项目公共数据进行统一管理。而且可以按照不同的业务功能将数据状态分模块管理。另外&#xff0c;对于网页刷新导致Vuex状态丢失的问题可以使用vuex-persistedstate插件配置将数据保存在localStorage或者sessionStorage中。 本…

「Python|场景案例」如何给图片添加水印

本文主要介绍如何使用python的PIL库给图片增加水印 文章目录背景说明工具准备处理步骤源代码处理效果展示背景说明 当我们想给一些图片添加水印的时候&#xff0c;尤其是图片数量较多的时候&#xff0c;就可以使用python进行自动化处理。包括但不限于在自媒体上发布自己的各种…

如何使用自助式商业智能 (BI) 避免组织中的数据孤岛

许多组织都存在数据问题。当许多员工远程工作&#xff08;或在混合环境中&#xff09;并在多个位置使用多个设备访问公司数据时&#xff0c;他们正在处理信息过载问题。这只会加剧数据孤岛的问题。 数据孤岛正是它听起来的样子&#xff1a;孤立在一个孤立的用户/环境中的数据&…

jdk版本和Class编译版本对应关系

JDK version和class file version(Class编译版本号)对应关系 JDK 17 61, JDK 16 60, JDK 15 59, JDK 14 58, JDK 13 57, JDK 12 56, JDK 11 55, JDK 10 54, JDK 9 53, JDK 8 52, JDK 7 51, JDK 6.0 50, JDK 5.0 …

数据结构-归并排序

一、概念及其介绍 归并排序&#xff08;Merge sort&#xff09;是建立在归并操作上的一种有效、稳定的排序算法&#xff0c;该算法是采用分治法(Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每…

三年“云改”,移动云这份答卷有多“硬”?

作者 | 曾响铃 文 | 响铃说 云计算是推动数字经济与实体经济深度融合的催化剂&#xff0c;是重点领域数字产业发展的助推器。近年来我国云计算产业发展提速&#xff0c;加快推动实体企业转型升级和创新发展。 2022年是移动云实施“云改”战略的第3年&#xff0c;也是移动云全…

【人工智能】基于五笔字型规范和人工神经网络的简中汉字识别【二】

环境搭建 一、NVIDIA驱动安装与更新二、Anaconda安装三、Pytorch安装四、验证CUDA和cudnn版本一、NVIDIA驱动安装与更新 显卡驱动就是用来驱动显卡的程序,它是硬件所对应的软件。 正常情况下,配有显卡的电脑都是安装有驱动程序的,但是有的时候驱动可能版本较低,所支持的 …

爬虫内容学习-工具类---Selenium

一、爬虫学习建议&#xff1a; 在编写python爬虫程序时&#xff0c;只需要做以下两件事&#xff1a; 发送GET请求&#xff0c;获取HTML [第一类] 解析HTML&#xff0c;获取数据 [第二类] 这两件事&#xff0c;python都有相应的库帮你去做&#xff0c;你只需要知道…

关乎你我,2022年都经历了哪些安全事件?|上云那些事

2022年&#xff0c;网络安全跟人们的工作生活关联愈发紧密。腾讯安全联合南方日报、南方&#xff0c;携手共建《上云那些事》栏目&#xff0c;为企业提供网络安全建设新思路&#xff0c;帮助大家及时发现身边的网络安全陷阱&#xff0c;提升安全意识和防范能力&#xff0c;减少…

论文阅读-虚假信息检测综述 - Fake News Detection on Social Media: A Data Mining Perspective

论文链接&#xff1a;https://arxiv.org/pdf/1708.01967.pdf 目录 摘要 1 引言 2. 假新闻定义 2.1 假新闻的定义 2.2 传统新闻媒体上的假新闻 2.3社交媒体上的假新闻 3.假新闻检测 3.1问题定义 3.2 特征提取 3.2.1 新闻内容特征 3.2.2 社会语境特征 3.3 模型构建 …

浅谈DNS域名解析的过程

用户在浏览器输入www.baidu.com时&#xff0c;DNS域名解析大致分为以下几个过程: 浏览器客户端检查自身有没有该域名的缓存&#xff1a; 如果浏览器有命中&#xff0c;直接返回该域名对应的IP地址&#xff0c;解析结束; (这个缓存可以设置TTL来控制有效时间&#xff0c;有点像A…

用C++求两个数的最大公约数和最小公倍数。(数论的基础思想)

目录原理最大公约数最小公倍数代码运行结果原理 最大公约数 有两个数字n和m。现在要求两个数字的最大公约数。 例如&#xff1a;n为18&#xff0c;m为4. 正常我们的思路求解最大公约数是暴力破解&#xff0c;遍历一遍公约数&#xff0c;取最大的那个&#xff0c;但是这样有一…

关闭Mac的Microsoft AutoUpdate弹框提示

macOS安装Microsoft Office for Mac之后&#xff0c;有时候会弹出Microsoft Auto Update微软应用自动更新工具。就像下面这样&#xff1a;&#xff08;我不知道您会不会烦&#xff0c;我是烦了&#xff09; 如果您也和我一样&#xff0c;不喜欢这样不经过允许就自动弹框的提示&…

【uiautomator2】 Android自动化测试框架

UiAutomator是Google提供的用来做安卓自动化测试的一个Java库. Uiautomator工作流程 1.在移动设备上安装atx-agent(守护进程),随后atx-agent启动uiautomator2服务(默认7912端口)进行监听 2.在PC上编写测试脚本并执行(相当于发送HTTP请求到移动设备的server端) 3.移动设备通过Wi…

python import失败解决方案

错误从何而起? 此时有这么一个目录结构 我们从a/b下执行python.exe ./main.py命令开始 案例: a/b/main.py导入a/package if __name__ "__main__":# 报错 ModuleNotFoundError: No module named packageimport package # 报错 ImportError: attempted relative…

Netty网络编程 - NIO基础

一. NIO 基础 non-blocking io 非阻塞 IO 1. 三大组件 1.1 Channel & Buffer channel 有一点类似于 stream&#xff0c;它就是读写数据的双向通道&#xff0c;可以从 channel 将数据读入 buffer&#xff0c;也可以将 buffer 的数据写入 channel&#xff0c;而之前的 st…

时间序列分析之auto_arima自动调参

背景 我们在进行ARIMA建模时&#xff0c;有一个非常重要的事情就是确定其中超参数p, d, q。 一般的流程需要先根据平稳性来确认差分的阶数d&#xff0c;然后根据平稳序列来观察ACF图和PACF图来确认p和q&#xff0c;当然中间还要根据网格训练查看AIC的值来确认&#xff0c;真个…