Day54 | 灵神 | 相向双指针:两数之和II-输入有序数组三数之和

Day54 | 灵神 | 相向双指针:两数之和II-输入有序数组&&三数之和

两数之和 三数之和【基础算法精讲 01】_哔哩哔哩_bilibili

文章目录

  • Day54 | 灵神 | 相向双指针:两数之和II-输入有序数组&&三数之和
    • 167.两数之和II-输入有序数组
      • 一个分析时间复杂度的新角度:
    • 15.三数之和
      • 去重

167.两数之和II-输入有序数组

167. 两数之和 II - 输入有序数组 - 力扣(LeetCode)

思路:

数组给咱们的是排序好的,那自然而然定义两根指针,一个在数组头l,一个在数组尾r

这样定义的好处是

两根指针中间的数字一定比头指针要大,一定比尾指针要小

如果两指针之和大于target的话,那中间某个数加上尾指针肯定也比target要大,那说明两个数加起来大了,那就把右边大的数字减小一点

如果两指针之和小于target的话,那头指针加上中间某个数肯定也比target要小,那说明两个数加起来小了,那就把左边大的数字增大一点

如果两指针之和等于target的话,那说明我们找到了答案直接返回就行

举例:

2 4 6 8 9 target=12

一开始 2 + 9=11小于12,那么不管是2和4,6,8哪个数字加都不可能达到12了,说明左边的选小了(同时也说明2肯定不会是答案了,就把2排除了,在4,6,8,9中选答案)

后来 4 + 9=13,大于12,那么不管是6,8哪个和9加都不可能比12小了,说明右边选大了(同时也说明9肯定不是答案了,就把9排除了,在4,6,8中选答案)

完整代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int l=0,r=numbers.size()-1;
        while(l<r)
        {
            if(numbers[l]+numbers[r]>target)
                r--;
            else if(numbers[l]+numbers[r]<target)
                l++;
            else
                return {l+1,r+1};
        }
        return {l+1,r+1};
    }
};

一个分析时间复杂度的新角度:

为什么双指针能从暴力算法的O(n²)优化到O(n)呢?

我们可以试着量化得到的信息

暴力做法中,我们是拿着两个数字加起来和target比一比大小,我们花费了O(1)的时间,得到了O(1)的信息

而双指针做法中,我们利用单调性这个性质,只要这两个数加起来比target大,那我就知道数组中比两个数中较大的数大的那边全都不行,我们花费了O(1)的时间,却得到了O(n)的信息,所以我们可以从O(n²)优化到O(n)。

15.三数之和

15. 三数之和 - 力扣(LeetCode)

思路:

跟着上一题的思路走。上一次是nums[l]和nums[r]和target比大小

nums[l]+nums[r]=target 

的时候我们就找到了答案,这一题只不过是转换为了

nums[l]+nums[r]-target = 0
nums[l]+nums[r]+nums[i] = 0

我们要找的就是

nums[i]在什么时候等于-target就行,在转换一下

其实就是找

nums[l]+nums[r]= -nums[i]

所以上一题是一个数组里面找到两个数加起来是一个固定的数target

这一题就一个数组里面找到两个数加起来是一个变化的数字nums[i]

那么只需要在上一题的代码上加一层循环,循环i就完事了

注意:不要忘记了排序,因为有序的情况下我们才用的双向双指针

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size()-2;i++)
        {
            int l=i+1,r=nums.size()-1;
            while(l<r)
            {
                if(nums[l]+nums[r]+nums[i]>0)
                    r--;
                else if(nums[l]+nums[r]+nums[i]<0)
                    l++;
                else
                {
                    res.push_back({nums[i],nums[l],nums[r]});
                    l++;r--;
                }
            }
        }
        return res;
    }
};

这是跟着上一题的思路可以写到的地方

去重

1.对i去重

if(i&&nums[i]==nums[i-1])
	continue;

就是i在大于0时,如果和上一个i值一样的话那就直接跳过

2.对l和r进行优化

while(l<r&&nums[l]==nums[l-1]) l++;
while(l<r&&nums[r]==nums[r+1]) r--;

对l和r和 对i的操作是一样的

完整代码:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size()-2;i++)
        {
            int l=i+1,r=nums.size()-1;
            if(i&&nums[i]==nums[i-1])
                continue;
            /*
            if (x + nums[i + 1] + nums[i + 2] > 0) break; // 优化一  前三个数字加起来都大于target了,就不用再算后面了
            if (x + nums[n - 2] + nums[n - 1] < 0) continue; // 优化二 第一个数和最后两个数加起来都小于0了,那后面的数也没必要遍历了,直接去遍历下一个i值
            */
            while(l<r)
            {
                if(nums[l]+nums[r]+nums[i]>0)
                    r--;
                else if(nums[l]+nums[r]+nums[i]<0)
                    l++;
                else
                {
                    res.push_back({nums[i],nums[l],nums[r]});
                    l++;r--;
                    while(l<r&&nums[l]==nums[l-1]) l++;
                    while(l<r&&nums[r]==nums[r+1]) r--;
                }

            }
        }
        return res;
    }
};

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

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

相关文章

基于蓝牙通信的手机遥控智能灯(论文+源码)

1.系统设计 灯具作为人们日常生活的照明工具为人们生活提供光亮&#xff0c;本次基于蓝牙通信的手机遥控智能灯设计功能如下&#xff1a; &#xff08;1&#xff09;用户可以通过蓝牙通信模块的作用下&#xff0c;在手机端遥控切换智能灯不同的工作模式&#xff1b; &#x…

IDEA搭建SpringBoot,MyBatis,Mysql工程项目

目录 一、前言 二、项目结构 三、初始化项目 四、SpringBoot项目集成Mybatis编写接口 五、代码仓库 一、前言 构建一个基于Spring Boot框架的现代化Web应用程序&#xff0c;以满足[公司/组织名称]对于[业务需求描述]的需求。通过利用Spring Boot简化企业级应用开发的优势&…

[HNCTF 2022 Week1]你想学密码吗?

下载附件用记事本打开 把这些代码放在pytho中 # encode utf-8 # python3 # pycryptodemo 3.12.0import Crypto.PublicKey as pk from hashlib import md5 from functools import reducea sum([len(str(i)) for i in pk.__dict__]) funcs list(pk.__dict__.keys()) b reduc…

OneCode:开启高效编程新时代——企业定制出码手册

一、概述 OneCode 的 DSM&#xff08;领域特定建模&#xff09;出码模块是一个强大的工具&#xff0c;它支持多种建模方式&#xff0c;并具有强大的模型转换与集成能力&#xff0c;能够提升开发效率和代码质量&#xff0c;同时方便团队协作与知识传承&#xff0c;还具备方便的仿…

【UE5】pmx导入UE5,套动作。(防止“气球人”现象。

参考视频&#xff1a;UE5Animation 16: MMD模型與動作導入 (繁中自動字幕) 问题所在&#xff1a; 做法记录&#xff08;自用&#xff09; 1.导入pmx&#xff0c;删除这两个。 2.转换给blender&#xff0c;清理节点。 3.导出时&#xff0c;内嵌贴图&#xff0c;选“复制”。 …

[x86 ubuntu22.04]投影模式选择“只使用外部”,外部edp屏幕无背光

1 问题描述 CPU&#xff1a;G6900E OS&#xff1a;ubuntu22.04 Kernel&#xff1a;6.8.0-49-generic 系统下有两个一样的 edp 屏幕&#xff0c;投影模式选择“只使用外部”&#xff0c;内部 edp 屏幕灭&#xff0c;外部 edp 屏幕无背光。DP-1 是外部 edp 屏幕&#xff0c;eDP-1…

【zlm】 webrtc源码讲解三(总结)

目录 setsdp onwrite ​编辑 play 参考 setsdp onwrite play 参考 【zlm】 webrtc源码讲解_zlm webrtc-CSDN博客 【zlm】 webrtc源码讲解&#xff08;二&#xff09;_webrtc 源码-CSDN博客

Python拆分Excel - 将工作簿或工作表拆分为多个文件

在日常工作中&#xff0c;我们经常需要处理包含大量数据的Excel文件。这些文件可能包含不同的表格、图表和工作表&#xff0c;使得数据管理和分析变得复杂。为了提高效率和准确性&#xff0c;我们可以将一个Excel文件或其中某一个工作表按需求拆分为多个文件&#xff0c;以便更…

作业Day4: 链表函数封装 ; 思维导图

目录 作业&#xff1a;实现链表剩下的操作&#xff1a; 任意位置删除 按位置修改 按值查找返回地址 反转 销毁 运行结果 思维导图 作业&#xff1a;实现链表剩下的操作&#xff1a; 1>任意位置删除 2>按位置修改 3>按值查找返回地址 4>反转 5>销毁 任意…

Docker:Dockerfile(补充四)

这里写目录标题 1. Dockerfile常见指令1.1 DockerFile例子 2. 一些其他命令 1. Dockerfile常见指令 简单的dockerFile文件 FROM openjdk:17LABEL authorleifengyangCOPY app.jar /app.jarEXPOSE 8080ENTRYPOINT ["java","-jar","/app.jar"]# 使…

jmeter中的prev对象

在jmeter中通过beanshell、JSR223的各种处理器编写脚本时&#xff0c;都会看到页面上有这样的说明 这些ctx、vars、props、OUT、sampler、prev等等都是可以直接在脚本中使用的对象&#xff0c;由jmeter抛出 今天主要讲一下prev的使用 SampleResult prev jmctx.getPreviousRe…

数据库管理系统——数据库设计

摘要&#xff1a;本博客讲解了数据库管理系统中的数据库设计相关内容&#xff0c;包括概念结构设计&#xff1a;E-R模型&#xff0c;逻辑结构设计&#xff1a;E-R模型到关系设计等内容。 目录 一、数据库设计和数据模型 1.1.数据库设计概述 1. 2.数据库结构概述 1.3.数据库…

Mac配置 Node镜像源的时候报错解决办法

在Mac电脑中配置国内镜像源的时候报错,提示权限问题,无法写入配置文件。本文提供解决方法,青测有效。 一、原因分析 遇到的错误是由于 .npm 目录下的文件被 root 用户所拥有,导致当前用户无法写入相关配置文件。 二、解决办法 在终端输入以下命令,输入管理员密码即可。 su…

【原生js案例】前端封装ajax请求及node连接 MySQL获取真实数据

上篇文章&#xff0c;我们封装了ajax方法来请求后端数据&#xff0c;这篇文章将介绍如何使用 Node.js 来连接 MySQL&#xff0c;并对数据库进行操作。 实现效果 代码实现 后端接口处理 const express require("express"); const connection require("../da…

使用FakeSMTP创建本地SMTP服务器接收邮件具体实现。

以下代码来自Let’s Go further节选。具体说明均为作者本人理解。 编辑邮件模版 主要包含三个template: subject&#xff1a;主题plainBody&#xff1a; 纯文本正文htmlBody&#xff1a;超文本语言正文 {{define "subject"}}Welcome to Greenlight!{{end}} {{def…

在Linux系统安装配置 MySQL 和 hive,hive配置为远程模式

前提&#xff1a;已安装配置好了Hadoop环境&#xff0c;因为hive的底层是Hadoop 1 Mysql安装 搜索Centos7自带的mariadb rpm -qa|grep mariadb 卸载mariadb rpm -e mariadb-libs-5.5.64-1.el7.x86_64 --nodeps 再搜索一次看看是否还存在 rpm -qa|grep mariadb 安装mysql 创…

【JetPack】Room数据库笔记

Room数据库笔记 ORM框架&#xff1a;对齐数据库数据结构与面向对象数据结构之间的关系&#xff0c;使开发编程只考虑面向对象不需要考虑数据库的结构 Entity : 数据实体&#xff0c;对应数据库中的表 <完成面向对象与数据库表结构的映射> 注解&#xff1a; 类添加注解…

OpenHarmony-4.HDI 框架

HDI 框架 1.HDI介绍 HDI&#xff08;Hardware Device Interface&#xff0c;硬件设备接口&#xff09;是HDF驱动框架为开发者提供的硬件规范化描述性接口&#xff0c;位于基础系统服务层和设备驱动层之间&#xff0c;是连通驱动程序和系统服务进行数据流通的桥梁&#xff0c;是…

AI Agent与MEME:技术与文化融合驱动Web3创新

AI Agent如何引领Web3新时代&#xff1f; 随着Web3与区块链技术的迅速发展&#xff0c;AI Agent作为人工智能与区块链的交汇点&#xff0c;正在逐步成为推动去中心化生态的重要力量。同时&#xff0c;MEME文化凭借其强大的社区驱动力和文化渗透力&#xff0c;在链上生态中扮演着…

接口测试-Fidder及jmeter使用

一、接口测试的基础 1.接口的含义 也叫做API&#xff0c;是一组定义、程序及协议的集合&#xff0c;提供访问一组例程的能力&#xff0c;无需访问源码获理解内部工作细节 2.接口的分类 代码内部的接口&#xff0c;程序模块间的接口&#xff0c;对于程序接口测试&#xff0c;需…