双指针(7)_单调性_三数之和

news2024/11/17 7:47:45

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

双指针(7)_单调性_三数之和

收录于专栏【经典算法练习
本专栏旨在分享学习C++的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 题目链接:

2.题目描述 :

3.解法 :

    解法一(暴力枚举) :

    算法思路 :

    代码展示 :

    结果分析 :

    解法二(排序 + 双指针) :

    算法思路 :

    图解流程 :

    代码展示 :

    结果分析 :

    4.总结 :


1. 题目链接:

OJ链接----. - 力扣(LeetCode)

2.题目描述 :

给你一个整数数组 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
  • -105 <= nums[i] <= 105

3.解法 :

    解法一(暴力枚举) :

    算法思路 :

1. 对整个数组进行排序

2. 三层循环遍历数组

3. 使用set去重 

    代码展示 :

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        set<vector<int>> T;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for(int i = 0; i < n - 2; i++)
            for(int j = i + 1; j < n; j++)
                for(int k = j + 1; k < n; k++)
                {
                    if(nums[i] + nums[j] + nums[k] == 0) 
                    {
                        T.insert({nums[i], nums[j], nums[k]});
                    }
                }

        vector<vector<int>> result(T.begin(), T.end());
        return result;
    }
};

 

    结果分析 :

由于数据范围是3000,所以我们这个三层循环就算有了排序的优化,也没能通过(只差5个例子), 

    解法二(排序 + 双指针) :

这里大家可以先去看查找总价格为目标值的两个商品这道题,那道题与本题思路很像

--双指针(6)_单调性_查找总价格为目标值的两个商品-CSDN博客

    算法思路 :

本题与两数之和类似,是非常经典的面试题

与两数之和稍微不同的是,题目中要求找到所有[不重复]的三元组.那我们可以利用在两数之和那里用的双指针思想,来对我们的暴力枚举做优化:

        i. 先排序

        ii. 然后固定一个数a:

        iii. 在这个数后面的区间内,使用双指针算法快速找到两个数之和等于-a即可

但是要注意的是,这道题需要有[去重]操作~

        i. 找到一个结果之后,left和right指针要[跳过重复]的元素

        ii. 当使用完一次双指针算法之后,固定a也要[跳过重复]的元素

    图解流程 :

开始我们就对数组进行排序,这样数组中的序列就是单调有序的,这样我们就可以使用双指针进行求解问题!!!

 

 固定一个数,剩下的数构成二元组,然后在二元组里面利用双指针进行寻找

如果left + right < -dest

说明right左边所有数加left都小于dest

那么left就无需遍历,left++

 

如果left + right > -dest

说明left右边所有数加right都大于dest

那么right就无需遍历,right--

 

如果left + right == -dest

说明找到题目符合条件的数,插入到vector

left++,right--

 

注意:(去重问题)

这里也是left + right == -dest

说明找到题目符合条件的数,插入到vector

left++,right--

但是这里要判断nums[left - 1] == nums[left] 如果相等left直接++

nums[right] == nums[right - 1] 如果相等直接--

 

 

进行去重处理后left指向1, right也指向1

此时left + right < -dest lest++

left < right(不满足)循环结束

dest++

 

dest++的小优化: 

当dest大于0时:

循环可以直接结束,因为我们的数组已经排序

left和right也一定是大于0的

 

去重的边界问题

left 和right:

它们两个去重时,可能会访问到未定义的内存,需要进行条件束缚

left < right

dest:

它在去重时也可能会访问到未定义的内存,也需要进行条件束缚\

dest < nums.size()

 

    代码展示 :

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;

        sort(nums.begin(), nums.end());
        
        int n = nums.size();

        for(int dest = 0; dest < n; )
        {
            if(nums[dest] > 0) break;
            int left = dest + 1, right = n - 1;

            while(left < right)
            {
                if(nums[left] + nums[right] < -nums[dest]) left++;
                else if(nums[left] + nums[right] > -nums[dest]) right--;
                else
                {
                    result.push_back({nums[dest], nums[left], nums[right]});
                    left++;
                    right--;
                    while(left < right && nums[left - 1] == nums[left]) left++;
                    while(left < right && nums[right] == nums[right + 1]) right--;
                }
            }
            
            dest++;
            while(dest < n && nums[dest] == nums[dest - 1]) dest++;
        }
        return result;
    }
};

 

    结果分析 :

顺利通过!!!
这道题很有价值,虽然难度是中等,但已经逼近困难了!

这道的思路其实不难(其实就是之前双指针(6)中那题一样的思想),它难的地方就在于如何去重,在去重的过程中是否会注意到一些细节问题!

    4.总结 :

 这道题使用的是排序 + 双指针算法

1. 排序:

2. 固定一个数a:

3. 在该数后面的区间内,利用双指针算法快速找到两个的和等于-a即可

处理细节问题:

1. 去重

        找到一种结果后,left和right指针要跳过重复元素

        当使用完一次双指针算法之后,i也需要跳过重复元素

2. 不漏

        找到一种结果后,不要停,缩小区间,继续寻找.

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

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

相关文章

【Redis】redis5种数据类型(string)

目录 redis5种数据类型和内部编码方式 redis单线程模型 string字符串类型相关命令 SET GET MSET MGET SETNX SETEX ​编辑PSETEX value值为整数&#xff0c;进行加减操作 INCR INCRBY DECR DECRBY INCRBYFLOAT APPEND GETRANGE SETRANGE STRLEN string的…

VMwareWorkstation安装UOS系统(1070版本)教程

UOS系统是一款国产信创操作系统。目前市面上主流的系统版本是1070&#xff0c;下面我们用虚拟机来安装一下这款系统。 创建虚拟机 首先&#xff0c;我们先打开VMwareWorkstation软件&#xff0c;新建虚拟机 选择自定义&#xff0c;点击下一步 点击下一步 选择稍后安装操作系统…

【通信管理之c++基础01】std::future

std::future https://en.cppreference.com/w/cpp/thread/future https://cplusplus.com/reference/future/future/ std::async #

实验一 局域网设计

一、实验目的 1.掌握网络工程中需求分析方法。 2.子网IP地址规划及子网间互相通信的方法。 3.掌握局域网的构建方法。 二、实验描述 某中学拟建设一个校园网&#xff0c;网络使用192.168.10.0/24这个地址段。计算机主要分布如下&#xff1a;两个学生机房各为10台&#xff…

数据库课程 CMU15-445 2023 Fall Project-0 项目记录

0. 实验结果 1. 环境配置 1.1 虚拟机Ubuntu 22.04.4 LTS 1.2 Vscode 插件安装clangd&#xff1a;代码补全 1.3 参考官方Project 0完成环境配置 1.4 获取到的代码&#xff0c;切换分支到2023 Fall git checkout fc57dab // 仓库中2023 Fall release版本的哈希值 git branch d…

WPF 保姆级教程怎么实现一个树形菜单

先看一下效果吧: 我们直接通过改造一下原版的TreeView来实现上面这个效果 我们先创建一个普通的TreeView 代码很简单: <TreeView><TreeViewItem Header"人事部"/><TreeViewItem Header"技术部"><TreeViewItem Header"技术部-1&q…

低代码平台:助力企业数字化转型的利器

正文&#xff1a; 在数字化时代的浪潮中&#xff0c;企业需要快速适应市场变化和技术进步。传统的软件开发方法往往由于开发周期长、成本高和对技术人员的依赖程度高&#xff0c;难以满足企业的快速响应需求。此时&#xff0c;低代码平台&#xff08;Low-Code Platform&#x…

干货分享|分享一款微软出品的工作效率神器 PowerToys

工具介绍&#xff1a;Microsoft PowerToys 是一组实用工具&#xff0c;可帮助高级用户调整和简化其 Windows 体验&#xff0c;从而提高工作效率。 安装步骤&#xff1a;直接打开微软商店安装即可&#xff0c;并且可以保证下载到最新版本。 功能介绍&#xff1a; 高级粘贴 高级…

js react 笔记 2

起因&#xff0c; 目的: 记录一些 js, react, css 1. 生成一个随机的 uuid // 需要先安装 crypto 模块 const { randomUUID } require(crypto);const uuid randomUUID(); console.log(uuid); // 输出类似 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d 2. 使用 props, 传递参数…

[uniapp/wx小程序] 关于cover-view滚动/点击穿透问题的解决方案/cover-view 的坑

情况&#xff1a;如果在原生组件上&#xff0c;搞了一些弹窗、覆盖层、操作栏等等的东西&#xff0c;有层级的情况&#xff0c;就会出现事件穿透的问题 问题&#xff1a;自然会想到官方给出的解决方案&#xff1a;使用cover-view。但有时穿透问题虽然解决了&#xff0c;但会出…

【NanoEdgeAIStudio】初次体验

本文前言 NanoEdge ai Studio是ST提供的免费软件&#xff0c;可以轻松地将ai添加到任何Arm Cortex-M MCU上运行的任何嵌入式项目中。官网首页&#xff1a;NanoEdge AI Studio&#xff0c;官方文档&#xff1a;AI:NanoEdge AI Studio。官方文档写的很详细&#xff0c;建议观看。…

Python 从入门到实战12(流程控制-跳出循环语句)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们通过举例学习了流程控制语句中的循环语句。今天继续讨…

【数据结构】顺序表和链表——链表(包含大量经典链表算法题)

文章目录 1. 单链表1.1 概念与结构1.1.1 结点1.1.2 链表的性质1.1.3 链表的打印 1.2 实现单链表1.3 链表的分类1.4 单链表算法题1.4.1 移除链表元素1.4.2 反转链表1.4.3 链表的中间结点1.4.4 合并两个有序链表1.4.5 链表分割1.4.6 链表的回文结构1.4.7 相交链表1.4.8 环形链表1…

【运维监控】influxdb 2.0+grafana 监控java 虚拟机以及方法耗时情况(完整版)

关于java应用的监控本系列有文章如下&#xff1a; 【运维监控】influxdb 2.0telegraf 监控tomcat 8.5运行情况 【运维监控】influxdb 2.0grafana 监控java 虚拟机以及方法耗时情况 【运维监控】Prometheusgrafana监控tomcat运行情况 【运维监控】Prometheusgrafana监控spring b…

软考科目傻傻分不清?一次搞懂各科目考核内容!小白不再纠结!

2024年下半年软考报名已经逐步进入尾声了&#xff0c;大部分考生都已完成报名&#xff0c;但有不少小白因为是第一次报考&#xff0c;对各科目傻傻分不清&#xff0c;导致报错了科目…… 这种情况很可能会影响考试&#xff0c;浪费了一次报考机会。而为了尽量避免这一情况再发生…

个人简历 (自己设计的)

欢迎大家来观看。 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" co…

国产“小钢炮”MiniCPM3-4B:小参数,大能量!

前沿科技速递&#x1f680; 在 AI 大模型浪潮中&#xff0c;国内厂商面壁智能再次突破&#xff0c;推出了其最新的“小钢炮”系列——MiniCPM 3.0。这款全新模型不仅实现了在移动设备上运行 GPT-3.5 级别的能力&#xff0c;而且具备超强的推理、检索与代码解释功能。MiniCPM 3.…

Python必知必会:程序员必须知道的22个Python单行代码!

今天给大家分享24个每个Python程序员都必须知道的单行代码&#xff0c;帮你写出更简洁、更优雅、更高效的代码。 1. 列表推导式 列表推导式&#xff08;List Comprehensions&#xff09;可以提供一种简洁的方式创建列表。相较于传统的循环&#xff0c;列表推导式更高效、可读…

240909-ChuanhuChatGPT集成Ollama的环境配置

A. 最终效果 B. 需求文件 requirements.txt (至少需要安装这个&#xff0c;具体参见官网)requirements_advanced.txt &#xff08;如果安装了Ollama&#xff0c;并且可以进行对话&#xff0c;可以不需要安装&#xff0c;具体参见官网&#xff09;requirements_succcess.txt&am…

Qt5.4.1连接odbc驱动操作达梦数据库

Qt5.4.1连接odbc驱动操作达梦数据库 1 环境介绍2 Qt5.4.1 安装2.1 图形化界面安装Qt5.4.12.2 配置Qt5.4.1 环境变量2.3 Qt5.4.1 生成 libqsqlodbc.so 并配置2.3.1 生成Makefile2.3.2 查看 libqsqlodbc.so 文件并配置 3 配置Qt测试用例4 达梦数据库学习使用列表 1 环境介绍 CPU…