【leetcode】双指针(二)

标题: 【leetcode】双指针(二)

水墨不写bug

9ad320e756224fc8971909cde5e7143e.jpeg


正文开始:

 

(一)总和为目标值的两个数


        购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回任一结果即可。

示例 1:

输入:price = [3, 9, 12, 15], target = 18
输出:[3,15] 或者 [15,3]
示例 2:

输入:price = [8, 21, 27, 34, 52, 66], target = 61
输出:[27,34] 或者 [34,27]
提示:

1 <= price.length <= 10^5
1 <= price[i] <= 10^6
1 <= target <= 2*10^6

 

首先是暴力算法:

        枚举出所有的两个数形成的集合,判断两数之和是否等于target即可;

        优化:

        a,初始化left , right 分别指向数组的左右两端(这里不是真正意义上的指针,⽽是数组的下标)
        b, 当 left < right 的时候,⼀直循环
         i、当 nums[left] + nums[right] == target 时,说明找到结果,记录结果,并且返回;
         ii、当 nums[left] + nums[right] < target 时:
        • 对于升序数组nums[left] ,此时 nums[right] 相当于是nums[left] 能碰到的最⼤值。如果此时不符合要求,说明在这个数组里面,没有别的数满足 nums[left] 的要求了。
        因此,我们可以⼤胆舍去这个数,让 left++ ,去比较下⼀组数据;
        • 那对于 nums[right] ⽽⾔,由于此时两数之和是⼩于⽬标值的, nums[right] 还可以选择⽐nums[left] ⼤的值继续努⼒达到⽬标值,因此 right 指针我们暂时不动;
        iii、 当 nums[left] + nums[right] > target 时,同理我们可以舍去nums[right] 。让 right-- ,继续⽐较下⼀组数据,⽽ left 指针不变(因为它还是可以去匹配比nums[right] 更⼩的数的)。

 

(一)三数之和

        给你一个整数数组 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

         其实在两数之和的基础上,三数之和就显得简单了许多,如果直接给你一道三数之和,也许你无法想到正确的符合时间复杂度的算法,但是我们在了解了两数之和之后,就会发现三数之和其实是两数之和的一般化的情况:

算法思想:

        对于任意数组,我们可以先固定一个数,然后在剩余的数组中找到两个数,并使这两个数的和等于固定的数的相反数即可;

        这也就是降维思想来解决问题,当我们理解了三数之和的解法之后,就会发现两数之和的查找其实就是三数之和固定一个固定值后对剩余两数的查找;

        

class Solution {
public:

    vector<vector<int>> threeSum(vector<int>& nums) 
    {
        vector<vector<int>> ret;
        int left = 0,right = 0;
        //排序
        sort(nums.begin(),nums.end());
        int n = nums.size();
        for(int target = 0 ;nums[target] <= 0 && (target < n-1) ; target++ )
        {
            if( ( target > 0)&&nums[target] == nums[target - 1] )
            {
                continue;
            }
            for(left = target+1,right = n-1;left < right; )
            {
                if(nums[left] + nums[right] + nums[target] < 0 && (left < right)) 
                {
                   ++left;
                }
                else if(nums[left] + nums[right] + nums[target] > 0 && (left < right)) 
                {
                    --right;
                }
                else
                {
                    
                     //插入数据
                    ret.push_back( {nums[left],nums[right],nums[target]} );
                    //处理连续跨越问题和越界问题
                    while(nums[++left] == nums[left-1] && (left < right));
                    
                    while(nums[--right] == nums[right+1] && (left < right));
                }
            }
        }
        return ret;
    }
};

 

(二)四数之和

 

        给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abc 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

 

示例 1:

输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

示例 2:

输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

 

提示:

  • 1 <= nums.length <= 200
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9

        在两数之和与三数之和的思路延续上,我们也可以类似的类比出四数之和的解决方法:

思路:

        对于任意一个数组找到和为target的数,

        可以先固定一个数组中的数a,在除此数a的其余数组中找到target-a的数;

        接下来固定一个数b,在除此数b和数a的其余数组中找到target-a-b的数;

        再固定一个数c,在除此数c和数b和数a的其余数组中找到target-a-b-c的数;

        现在这个问题就退化成了二数之和的问题:

        对任意数组,在除此数c和数b和数a的其余数组中找到target-a-b-c的数。

这样我们将这个问题不断简化,就将复杂的问题转化为简单的我们可以解决的问题。

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ret;
        //排序
        sort(nums.begin(),nums.end());
        int n = nums.size() ;
        
        //找和为target的4个数
        for(int a = 0;a < n-1;)
        {
            //找和为target-nums[a]的3个数
            for(int b = a+1;b < n-1;)
            {
                
                //找和为target-nums[a]-nums[b]的2个数,这时可利用双指针
                for(int left = b+1,right = n-1;left < right;)
                {
                    long sum = (long)nums[a] + (long)nums[b] + (long)nums[left] + (long)nums[right];

                    if( sum < target && (left < right))
                    {
                        ++left;
                    }
                    else if(sum > target && (left < right))
                    {
                        --right;
                    }
                    else 
                    {
                        ret.push_back( { nums[a] , nums[b] , nums[left] , nums[right] } );
                        while(nums[++left] == nums[left-1] && (left < right));
                        while(nums[--right] == nums[right+1] && (left < right));
                    }
                }
                b++;
                while(nums[b] == nums[b-1] && (b < n-1)) b++;
            }
            a++;
            while(nums[a] == nums[a-1] && (a < n-1 )) a++;
        }
        return ret;
    }
};

回顾

目录

(一)总和为目标值的两个数

(一)三数之和

(二)四数之和

 


完~

未经作者同意禁止转载

 

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

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

相关文章

kettle使用MD5加密增量获取接口数据

kettle使用MD5加密增量获取接口数据 场景介绍&#xff1a; 使用JavaScript组件进行MD5加密得到Http header&#xff0c;调用API接口增量获取接口数据&#xff0c;使用json input组件解析数据入库 案例适用范围&#xff1a; MD5加密可参考、增量过程可参考、调用API接口获取…

【TI毫米波雷达】IWR6843AOP的官方文件资源名称BUG,选择xwr68xx还是xwr64xx,及需要注意的问题

【TI毫米波雷达】IWR6843AOP的官方文件资源名称BUG&#xff0c;选择xwr68xx还是xwr64xx&#xff0c;及需要注意的问题 文章目录 demo工程out_of_box文件调试bin文件名称需要注意的问题附录&#xff1a;结构框架雷达基本原理叙述雷达天线排列位置芯片框架Demo工程功能CCS工程导…

这里有份百度Create大会超长剧透,请查收!

作者简介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

19c使用Datapump做数据迁移

环境&#xff1a; 源库目标库IP192.168.37.200192.168.37.201系统版本RedHat 7.9RedHat 7.9数据库版本19.3.0.0.019.3.0.0.0SIDbegtarhostnamebegtar数据量412KB 详细说明&#xff1a;因为只是做练习&#xff0c;这里采用了两个单例19c作为源端和目的端服务器&#xff0c;环境…

【网站项目】面向学生成绩分析系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

技术揭秘:如何打造完美互动的充电桩硬件与服务平台?

充电桩平台全套源码地址 https://gitee.com/chouleng/cdzkjjh.git 这张图像是一个系统或服务的架构图。以下是对图中各个部分的描述&#xff1a; 前端&#xff1a; 位于图像的顶部&#xff0c;颜色为浅绿色。用户服务端&#xff1a; 紧邻前端&#xff0c;颜色为淡黄色。设备服…

基于java+SpringBoot+Vue的校园交友网站设计与实现

基于javaSpringBootVue的校园交友网站设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot MyBatis工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 后台展示 系统简介 整体功能包含&#xff1a; 校园交友网站是一个为在校师生提供一个交流互动、寻找朋友的…

CSS3 实现文本与图片横向无限滚动动画

文章目录 1. 实现效果2.html结构3. css代码 1. 实现效果 gif录屏比较卡&#xff0c;实际很湿滑&#xff0c;因为是css动画实现的 2.html结构 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"…

[蓝桥杯练习题]出差

一道DJ题,重要的是隔离时间,把隔离时间加在边权上即可 现实生活的题大多都是无向图建图,需要边的两端点各自上邻接表和相同权重 #include<bits/stdc.h> using namespace std; #define ll long long const int N1005; const int M10005; struct edge{int to;ll w;edge(int…

招聘信息分享(第一期)

今天给大家带来——测绘、地信、遥感领域的事业单位招聘信息&#xff01;这也是我自己在关注的&#xff0c;自己应聘单位大多时间已经截至&#xff0c;后期会陆续分享&#xff0c;先分享近期招聘的事业单位 文章目录 1、宁夏大学2024年人才招聘2、甘肃有色冶金职业技术学院3、…

【大模型】大模型 CPU 推理之 llama.cpp

【大模型】大模型 CPU 推理之 llama.cpp llama.cpp安装llama.cppMemory/Disk RequirementsQuantization测试推理下载模型测试 参考 llama.cpp 描述 The main goal of llama.cpp is to enable LLM inference with minimal setup and state-of-the-art performance on a wide var…

数据分析之POWER BI Desktop可视化应用案列

在power bi中导入数据 导入前期建好的模型 简单介绍&#xff08;power bi desktop&#xff09; 将右边字段全部展开 各类数据 所作的模型 在excel中是单向的&#xff0c;power bi 中可以是双向的 右键单击----点击属性 选择两个---在两个方向上应用安全筛选器 变为双向的…

域名HTTPS证书免费获取渠道

SSL证书的优势 数据加密&#xff1a;SSL证书通过SSL/TLS协议为网站与用户之间的数据传输提供加密保护。这意味着所有在浏览器和服务器之间交换的信息&#xff08;如登录凭据、个人数据、支付详情等&#xff09;都经过加密处理&#xff0c;即使被第三方截获&#xff0c;也无法解…

提效提速的快捷回复工具

在数字化交流日益增长的今天&#xff0c;客服工作显得尤为重要。为了提升对话质量和回复速度&#xff0c;同时减少重复劳动&#xff0c;我同事给我介绍了一款快捷回复工具&#xff0c;叫做客服宝聊天助手。我用了几天真心觉得好好用&#xff0c;今天特地分享这个软件给你们&…

台湾花莲地震已致4死97伤,地震时刻,你需要知道的一切

近日&#xff0c;台湾花莲县海域发生了一次强震&#xff0c;引发了广泛关注。据中国地震台网测定&#xff0c;这次地震的震级高达7.3级&#xff0c;震源深度为12公里&#xff0c;造成了台湾全岛范围内的震感&#xff0c;以及福建、广东等地的明显震感。在这样的紧急情况下&…

防火墙状态检测和会话机制

FW对TCP&#xff0c;UDP和ICMP协议的报文创建会话

下载与安装Latex(windows简洁板)

总共要安装两个软件&#xff1a;TeX Live与TeX Studio 下载与安装TeX Live 下载 下载地址&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/CTAN/systems/texlive/Images/ 点击&#xff1a; texlive2024.iso 文件很大&#xff0c;可能会慢点 2. 安装 下载好了iso文件&…

Harmony创建Page省事小技巧

在创建Page页面时&#xff0c;选择ArkTS File时&#xff0c;创建的文件不会自动生成基础代码&#xff0c;也不会自动在main_page.json中自动进行注册&#xff0c;如何解决问题呢&#xff0c;其实很简单创建Page页面时选择Page项后就会创建Page文件&#xff0c;创建完的页面会自…

C++之类和对象的中篇

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary_walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…