【优选算法】详解target类求和问题(附总结)

目录

1.两数求和

题目:

算法思路:

代码:

2.!!!三数之和

题目

算法思路:

代码:

3.四数字和

题目:

算法思路:

代码:

总结&易错点:


1.两数求和

 剑指Offer57.和为s的两个数字

题目:

购物车内的商品价格按照升序记录于数组 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]

算法思路:

双指针-对撞指针: 注意到本题是升序的数组,因此可以⽤「对撞指针」优化时间复杂度。

算法流程(附带算法分析,为什么可以使⽤对撞指针)

 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] 更⼩的数的)。

代码:

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {//left++ right-- num+num=targetint n=nums.size();int left=0,right=n-1;while(left!=right){int sum=nums[left]+nums[right];if(sum<target)left++;else if(sum>target)right--;elsereturn {nums[left],nums[right]};//vector用大括号}return {-1,-1};//注意返回值的设定}
};

2.!!!三数之和

15.三数之和(灵魂去重类题

题目

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

算法思路:

(排序+双指针)

 本题与两数之和类似,是⾮常经典的⾯试题。与两数之和稍微不同的是,题⽬中要求找到所有「不重复」的三元组。

那我们可以利⽤在两数之和 那⾥⽤的双指针思想,来对我们的暴⼒枚举做优化:

i. 先排序;

ii. 然后固定⼀个数a

 iii. 在这个数后⾯的区间内,使⽤「双指针算法」快速找到两个数之和等于-a 即可。 但是要注意的是,这道题⾥⾯需要有「去重」操作~ 

  • i. 找到⼀个结果之后, left 和right 指针要「跳过重复」的元素
  •  ii. 当使⽤完⼀次双指针算法之后,固定的a 也要「跳过重复」的元素。

代码:

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(), nums.end());//排序// 设置一个ret来接收返回类型vector<vector<int>> ret;int n = nums.size();for (int c = 0; c <= n - 3;) {// 优化if (nums[c] > 0)break;int x = -nums[c];                // 是数字不是下标int left = c + 1, right = n - 1; // 是变换的,要在循环体里面定义while (left < right) {int sum = nums[left] + nums[right];if (sum < x)left++;else if (sum > x)right--;else {ret.push_back({ nums[c], nums[left], nums[right] });left++;right--;// 去重,while重新加一个条件运行while (left < right && nums[left] == nums[left - 1])left++; // 如果相等,就++跳过while (right > left && nums[right] == nums[right + 1])//不要糊涂,要清楚的列出伪代码!!right--;}}// 去重ic++;while (c <= n - 3 && nums[c] == nums[c - 1])c++; // 在循环内如果还出现这个相等条件,就再++// 在哪一步判断完之后需要执行去重,就在后面加上出现条件的处理}return ret; // 对于链表数组的理解}
};

3.四数字和

18.四数之和

题目:

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

0 <= a, b, c, d < n
a、b、c 和 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]]

算法思路:

a. 依次固定⼀个数a ;

 b. 在这个数a 的后⾯区间上,利⽤「三数之和」找到三个数,使这三个数的和等于target - a 即可。

代码:

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();for(int i=0;i<n; )//固定a{for(int j=i+1;j<n; )//固定b{//双指针int left=j+1,right=n-1;long long aim=(long long)target-nums[i]-nums[j];//可能很大,所以用long long来设置while(left<right){int sum=nums[left]+nums[right];//sum每次都要重新刷新if(sum<aim) left++;else if(sum>aim) right--;else{ret.push_back({nums[i],nums[j],nums[left++],nums[right--]});//去重1while(left<right&&nums[left]==nums[left-1])left++;//和前一个相等,就跳过while(left<right&&nums[right]==nums[right+1])right--;//和后一个相等就跳过,不要糊涂}}//去重2j++;while(j<n&&nums[j]==nums[j-1])j++;}i++;//每次到了下一个,就要判断一下,是否重复,重复就要跳过while(i<n&&nums[i]==nums[i-1])i++;}return ret;}
};

总结&易错点:

根据条件判断,对双指针进行移动求解

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

csdn上传图片失败解决办法

今天下午写笔记&#xff0c;上传图片的时候总是出现图片上传不成功。查询了下解决方案&#xff1a; C:\Windows\System32\drivers\etc &#xff0c;使用管理员打开hosts文件加入&#xff1a; 49.7.22.7 csdn-img-blog.oss-cn-beijing.aliyuncs.com保存之后&#xff0c;&#x…

Mac怎么读取内存卡 Mac如何格式化内存卡

在今天的数字化时代&#xff0c;内存卡已经成为了我们生活中不可或缺的一部分。对于Mac电脑用户而言&#xff0c;正确地读取和管理内存卡中的数据至关重要。下面我们来看看Mac怎么读取内存卡&#xff0c;Mac如何格式化内存卡的相关内容。 一、Mac怎么读取内存卡 苹果电脑在读…

Nacos长轮询底层是怎么实现的?

点击下方“JavaEdge”&#xff0c;选择“设为星标” 第一时间关注技术干货&#xff01; 免责声明~ 任何文章不要过度深思&#xff01; 万事万物都经不起审视&#xff0c;因为世上没有同样的成长环境&#xff0c;也没有同样的认知水平&#xff0c;更「没有适用于所有人的解决方案…

Redis到底支不支持事务?

文章目录 一、概述二、使用1、正常执行&#xff1a;2、主动放弃事务3、全部回滚:4、部分支持事务:5、WATCH: 三、事务三阶段四、小结 redis是支持事务的&#xff0c;但是它与传统的关系型数据库中的事务是有所不同的 一、概述 概念: 可以一次执行多个命令&#xff0c;本质是一…

蓝牙安全入门——两道CTF题目复现

文章目录 蓝牙安全入门题目 low_energy_crypto获取私钥解密 题目 蓝牙钥匙的春天配对过程配对方法密钥分发数据加密安全漏洞和保护实际应用实际应用 蓝牙安全入门 &#x1f680;&#x1f680;最近一直对车联网比较感兴趣&#xff0c;但是面试官说我有些技术栈缺失&#xff0c;所…

CleanMyMac2024最新免费电脑Mac系统优化工具

大家好&#xff0c;我是你们的好朋友——软件评测专家&#xff0c;同时也是一名技术博主。今天我要给大家种草一个超级实用的Mac优化工具——CleanMyMac&#xff01; 作为一个长期使用macOS的用户&#xff0c;我深知系统运行时间长了&#xff0c;缓存文件、日志、临时文件等都会…

【数据结构与算法 经典例题】括号匹配问题

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法 经典例题》C语言 期待您的关注 ​​ 目录 一、问题描述 二、解题思路 &#x1f343;破解之道 &#x1f343;…

【C#线程设计】3:threadpool

实现&#xff1a; &#xff08;1&#xff09;.控件&#xff1a;group Box&#xff0c;text Box&#xff0c;check Box&#xff0c;label&#xff0c;botton&#xff0c;richtextbox 控件拉取见&#xff1a;https://blog.csdn.net/m0_74749240/article/details/139409510?spm1…

全球AI速递6.11

1.快手&#xff1a;发布“可灵”视频生成大模型。 2.OPPO&#xff1a;计划让约 5 千万用户的手机搭载生成式 AI。 3.腾讯&#xff1a;发布了针对混元文生图开源大模型&#xff08;混元DiT&#xff09;加速库。 4.Stability AI&#xff1a;开源Stable Audio Open AI 模型&am…

重新认识Word —— 制作简历

重新认识Word —— 制作简历 PPT的图形减除功能word中的设置调整页边距进行排版表格使用 我们之前把word长排版文本梳理了一遍&#xff0c;其实word还有另外的功能&#xff0c;比如说——制作简历。 在这之前&#xff0c;我们先讲一个小技巧&#xff1a; PPT的图形减除功能 …

重学Spring总结

1、Spring框架的诞生 文章目录 1、Spring框架的诞生1、BeanFactory 快速入门1.1、BeanFactory完成了loC思想的实现&#xff1a;1)导入Spring相关的依赖&#xff1a;2)定义Uservice接口及其UserviceImpl实现类&#xff1b;3)创建Bean的配置资源文件&#xff0c;文件名最好为&…

Windows 服务器Nginx 下载、部署、配置流程(图文教程)

不定期更新 目录 一、下载Nginx安装包 二、上传安装包 三、启动Nginx 四、Nginx常用命令 五、Nginx&#xff08;最小&#xff09;配置详解 六、Nginx&#xff08;基础&#xff09;配置详解 七、反向代理 八、负载均衡 九、动静分离 十、报错 一、下载Nginx安装包 四…

vue29:普通组件的注册使用

<template><div class"App"><!-- 头部组件 --><HmHeader></HmHeader><!-- 主体组件 --><HmMain></HmMain><!-- 底部组件 --><HmFooter></HmFooter><!-- 如果 HmFooter tab 出不来 → 需要配置…

通过技术优化财务规划报告,重塑企业体验

财务报告使企业的管理层能够及时、准确、清晰且一致地了解整个企业的财务业绩和风险机遇。它促进了企业内部利益相关者之间的沟通&#xff0c;从而支持基于数据驱动的洞察力提升和战略决策。但财务报告往往需要占用大量的时间来运行和准备&#xff0c;且可能使最终结论偏离核心…

腾讯云大数据ES Serverless

Elasticsearch&#xff1a;日志和搜索场景首选解决方案。 技术特点&#xff1a;分布式、全文搜索和数据分析引擎&#xff0c;可以对海量数据进行准实时地存储、搜索和统计分析。 ES的技术栈一共包含四个组件&#xff1a; 其中最核心的是Elasticsearch&#xff0c;可用于数据…

LVGL移植和图片显示

最近闲来无事&#xff0c;偶尔刷到了移植LVGL的教程&#xff0c;今天肝完了机械原理又移植完LVGL库&#xff0c;真是收获满满的一天&#xff0c;先接一杯水去。 回来了&#xff0c;发个朋友圈高级一下&#xff0c;好困。 lvgl v8.3移植及组件使用_lvgl界面编辑器-CSDN博客htt…

RAG:如何从0到1搭建一个RAG应用

通过本文你可以了解到&#xff1a; 什么是RAG&#xff1f;如何搭建一个RAG应用&#xff1f;目前开源的RAG应用有哪些&#xff1f; 大模型学习参考&#xff1a; 1.大模型学习资料整理&#xff1a;大模型学习资料整理&#xff1a;如何从0到1学习大模型&#xff0c;搭建个人或企业…

手机连接ESP8266的WIFI,进入内置网页,输入要显示的内容,在OLED显示屏上显示文本

在这篇技术博客中&#xff0c;我们将探讨如何使用ESP8266 Wi-Fi 模块和SSD1306 OLED显示屏&#xff0c;构建一个简易的信息显示和交互系统。此系统能够让用户通过一个简单的Web界面输入信息&#xff0c;并将其显示在OLED屏幕上。这种设备的应用非常广泛&#xff0c;可以用于智能…

vue实现pdf下载——html2canvas

html2canvas 官方文档https://html2canvas.hertzen.com/getting-started html2canvas 的原理是通过遍历DOM树,将每一个HTML元素转化为Canvas对象,并叠加到一起形成一张完整的图片或者PDF文件。 1. 安装插件 npm install html2canvas jspdf --save 2.使用&#xff08;页面已经…

Leetcode刷题笔记9

1. 两数之和 1. 两数之和 - 力扣&#xff08;LeetCode&#xff09; 解法一&#xff1a;暴力枚举 没什么好说的&#xff0c;直接使用两个for循环&#xff0c;i从第一个元素开始&#xff0c;j从第二个元素开始遍历并寻找 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a…