双指针解决两数之和的问题

leetcode刷题记录(C语言版)——两数之和 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出target的那整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。[0,1]因为 nums[0] + nums[1] == 9 ,返回 [0, 1]。[1,2][0,1]你可以想出一个时间复杂度小于O(n2)的算法吗? 阅读详情

很多事情大家都心知肚明,只是聪明人不说出来


关于两数之和的问题,一般都是给定数组nums和目标值target, 处理这种问题一般需要注意以下两点:

  1. 数组是否有序;

  2. 给定目标值target,根据两数之和与target的大小情况展开讨论:
    - 等于target
    - 小于target
    - 大于target

  3. 返回值是下标 or 方案数

    如果需要返回值是下标,则在数组无序的情况下,我们是不能通过排序 和双指针方案来解决的。

结合Leetcode的题目,我们对上面所列举的情况逐一来展开讨论。

第一类:等于target

1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

根据上面的总结我们可以找出关键点:

  1. 数组无序;
  2. 两数之和等于target的情况;
  3. 返回数组下标;

所以此题就排除了排序 + 双指针的解决方案。推荐使用哈希表将时间复杂度给降到常数级。

解题思路就是遍历数组,对于每一个元素num,查询是否存在对应的 target - num。

	public int[] twoSum(int[] nums, int target) {
        int[] result = new int[2];

        if(nums == null || nums.length == 0){
            return result;
        }
        // 注意key为nums[i],value为下标
        HashMap<Integer,Integer> hashMap = new HashMap<>();

        for(int i = 0;i < nums.length; i++){

            if(hashMap.containsKey(target-nums[i])){
                result[0] = i;
                result[1] = hashMap.get(target-nums[i]);
                return result;
            }

            hashMap.put(nums[i],i);
        }
        return result;
    }

PS : 也可以用哈希表存储target-nums[i]实现。原理是一样的。

1.2 常见问题

很多同学对这里的哈希表究竟谁为key,谁为value有所疑问?相信自己,不是只有你一个人有此困惑。

这里郑重声明:

  • key ——— 元素num[i] 或者 target-nums[i]
  • value ———— 元素下标

很多之所以困惑是 考虑到数组中存在重复元素时,其作为key会被覆盖的原因。
对于这个题目,题目中明确了只会存在一个有效答案。这样的话,就算有重复元素,找到一组解就直接返回啦。

那么问题来了,假设可能存在多组解的情况,这种解法还有效吗?

答曰:然也

举个例子:

输入用例为[1,1,2,5], target = 3

当遍历到第二个1的时候,hashMap会覆盖前面的1,然后继续执行。最终会返回[2,1]这组有效答案。

彩
纸上得来终觉浅,绝知此事要躬行

刷算法题时,很多时候不是我们没有思路,而是没有真正动起手去实现罢了。


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

给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。

关键点:

  1. 数组有序——非递减顺序排列;
  2. 找出满足相加之和等于目标数 target 的两个数;
  3. 返回下标且index1 < index2;
  4. 下标从1开始;

数组有序的情况下,双指针,舍我其谁?

如图所示

 public int[] twoSum(int[] numbers, int target) {
        int[] result = new int[2];
        if(numbers == null || numbers.length == 0){
            return result;
        }

        int left = 0;
        int right = numbers.length - 1;

        while(left < right){
           int sum =  numbers[left]+numbers[right];
            if( sum == target){
            	// 因为下标从1开始,
                result[0] = left+1;
                result[1] = right+1;
                return result;
            }

            if(sum < target){
                left++;
            }else{
                right--;
            }
        }

        return result;
    }

顺手补一刀吧—— 剑指 Offer 57. 和为s的两个数字


第二类:小于target

1099. 小于 K 的最大两数之和

给你一个整数数组 nums 和整数 k ,返回最大和 sum ,满足存在 i < j 使得 nums[i] + nums[j] = sum 且 sum < k 。如果没有满足此等式的 i,j 存在,则返回 -1 。

关键点:

  1. 数组无序
  2. (sum = nums[i] + nums[j]) < k;
  3. 返回 最大和sum尽可能的大;

不用想了,排序 + 双指针。

 public int twoSumLessThanK(int[] nums, int k) {
        if(nums == null || nums.length == 0){
            return -1;
        }

        Arrays.sort(nums);

        int left = 0;
        int right = nums.length-1;

        int result = -1;

        while(left < right){
            int sum = nums[left] + nums[right];
            if(sum >= k){
                right--;
            }else{
            	// 求最大和
                result = Math.max(result,sum);
                left++;
            }
        }

        return result;
    }

LCP 28. 采购方案

小力将 N 个零件的报价存于数组 nums。小力预算为 target,假定小力仅购买两个零件,要求购买零件的花费不超过预算,请问他有多少种采购方案。

注意:答案需要以 1e9 + 7 (1000000007) 为底取模,如:计算初始结果为:1000000008,请返回 1

总结出关键点:

  1. 数组无序;
  2. num[i] + num[j] <= target;
  3. 求符合条件的方案数;

这道题是竞赛题,我们来看一下同学们的常见问题:
在这里插入图片描述
对于我竟无言以对,唯有张飞三连送于大家。
在这里插入图片描述

解决此题有个核心要素:方案数的锁定(右边界 - 左边界)。
在这里插入图片描述

public int purchasePlans(int[] nums, int target) {
        if(nums == null || nums.length == 0){
            return 0;
        }
		// 排序
        Arrays.sort(nums);

        int result = 0;

        int left = 0;
        int right = nums.length - 1;

        while(left <= right){
            int sum = nums[left] + nums[right];
            if(sum > target){
                right --;
            }else{
            	// 这里利用[left,right]的元素都符合sum <= target的特性,直接得出方案数为right - left.
                result += (right - left);
                result %= (1000000007);
                left++;
            }
        }
        return result;
    }
[算法导论] 两数之和小于目标值a+b<=target, 二分+指针o(nlogn) [1,2,6,9] 6 1+2 一种组合 lt =input()[1:].split(']') l = list(map(int,lt[0].split(','))) m = int(lt[1].split(',')[-1]) MAX = 1e9+7 n = len(l) c = 0 l.sort() r = n-1 # r不用每次都赋初始值!因为排序后,i增加,右边界肯定<=r。 #!!!!!!!!!!!!!!!!!二分+指针,nlogn for i in range(n): if 阅读详情

相关推荐

VCSA 6.7证书更新全流程指南:从故障诊断到完整替换

本文详细介绍了VCSA 6.7证书更新的全流程,包括故障诊断、证书替换操作步骤及常见问题解决方案。通过使用官方脚本和证书管理器,帮助管理员快速解决证书过期问题,确保vCenter系统的稳定运行。特别强调了STS证书修复和全量证书重置的关键步骤,适用于vcsa6.7环境下的证书管理需求。

weixin_42634811的博客 450

算法:两数之和(two-sum)。

给定一个整数数组 nums和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。

孤芳不自赏 1万+

openvpn 安装 (Alibaba Cloud Linux release 3 (Soaring Falcon))

1.错误:configure: error: libnl-genl-3.0 package not found or too old. Is the development package and pkg-config (/usr/bin/pkg-config) installed?# ta.key在/etc/openvpn/server/目录下可以如下配置,否则需要写完整路径。# 配置账号密码登录客户端需要ca证书(可选)# 证书校验算法 配置上面生成的完整路径。# ca证书 配置上面生成的完整路径。

dubhe_zhao的博客 2150

双指针——两数之和,三数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。示例 1:输入:nums = [2,7,11,15], target = 9输出:[0,1]解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]。

qq_43556680的博客 1544

基于OpenSSL的CA建立及证书签发(签发多域名/IP)

自签SSL证书(多域名/IP) 本文基于以下环境: 内核信息:Linux zabbix 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux 系统版本:CentOS Linux release 7.6.1810 (Core) OpenSSL版本:OpenSSL 1.0.2k-fips 26 Jan 2017 【前言】 在基于OpenSSL的CA建立及证书签发一文中(后面统.

hobby云说 4647

新英格兰10机39节点matlab建模,ieee10机39节点系统数据

【实例简介】ieee10机39节点系统数据,主要是BPA数据!【实例截图】【核心代码】ne_039_bus└── ne_039_bus├── 039readme.doc├── bpa│ ├── 039bpa.dat│ ├── 039bpa.swi│ ├── LFerr.LIS│ ├── OneNote 目录.onetoc2│ └── STERR.LIS├── eurostag│...

weixin_39851809的博客 3273

LeetCode167. 两数之和Ⅱ - 输入有序数组

LeetCode167. 两数之和Ⅱ - 输入有序数组 给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。 以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 in

m0_56077202的博客 277

第1集:认识 Claude Code —— AI 编程新纪元

1. 定义 Claude Code:终端中的 AI 编程代理Claude Code 是 Anthropic 公司于 2025 年 5 月正式推出的命令行 AI 编程工具,它不只是一个代码补全工具,而是一个能够理解项目、自主执行任务的**终端 AI 代理(Agent)。它的核心理念是 **"生于终端,活于终端"** (lives in your terminal)。与深度嵌入图形界面(GUI)的工具不同,Claude Code 选择直接融入开发者最原始、最核心的工作环境——命令行。

dianziyao_的博客 865

漫画算法题:两数之和与三数之和

前一段时间,小灰分别讲解了两道leecode上的经典算法题:漫画:如何在数组中找到和为 “特定值” 的两个数?漫画:如何在数组中找到和为 “特定值” 的三个数?今天,小灰把这两道题整合起...

程序员小灰的博客 2880

【工具插件类教学】Unity翻书效果插件Book-Page Curl Pro教程

特征: • 从左到右和从右到左翻页 • 与画布缩放器 配合使用 • 可配置的自动翻转脚本 • 支持向页面 添加 UI 元素 • 支持透明页面 • 适用于“世界空间”画布

纯技术流日常开发商业开发记录总结等 3674

STM32N6570-DK识别STLINK问题,如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 2209

LeetCode——167. 两数之和 II - 输入有序数组(双指针)

文章目录167. 两数之和 II - 输入有序数组(双指针)题目思路**:代码 167. 两数之和 II - 输入有序数组(双指针) 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题目 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 函数应该返回这两个下标值 index1 和 inde

李霁明的博客 495

赛豆科技 AIVA 汽车智能体架构演进面试题与答案

摘要 赛豆科技AIVA汽车智能体架构从座舱AI演进到整车智能体,最终实现自进化的超级智能体。其核心是"先有AI再有车"的理念,将AI作为产品主轴而非附加功能。架构设计采用端-边-云协同,确保低延迟响应;整车智能体通过Planner、Tool Registry等关键组件实现自主决策;自进化机制结合车端个性化学习和云端群体学习,并设置多重安全验证。多域协作采用分层架构,关键安全功能仍由确定性逻辑控制。该架构实现了从被动响应到主动服务的范式转变,使车辆能够持续进化。

AI天才研究院 122

两数、三数之和问题

两数之和 双指针 两数之和问题显而意见是用双指针来写,要想使用双指针前提是数组提前有序。这道题的坑就在这里,数组无序,我们需要先排序,但是题目让返回的却是数字所在原数组的下标,如果已排序就乱了,因此有两种方法,一种就是我认为简单的我们在进行排序,只不过把下标和数组放在一起进行排序。 #include<bits/stdc++.h> int vis[100100]; //这里的默认为是大于号 bool cmp(pair<int,int>a, pair<int,int> b)

weixin_43310882 180

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

海智算法训练营第六天 | 第三章 哈希表part02 | 1两数之和 454四数相加II 15. 三数之和 18四数之和

题目:两数之和 这道题用map集合主要是因为有两个原因:1.有两个值需要判断,这时候map集合天然的优势,key—value键值对,key存储元素的值,value存储元素的下标。 2.数组长度不确定,而用哈希表数组的解法可能会浪费内存空间。解法:先将数组的元素值和下标通过循环逐一加入map集合中,同时在加入时判断map集合内是否有与其配对的target,如果有,就结束循环,并返回两个值的下标,map集合的下标就用map.get(key)方法求得。题目:四数相加 这道题因为仅仅只有四个数组,所以解法较

qq_74462324的博客 717

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

两数之和、三数之和、四数之和、K数之和

两数之和、三数之和、四数之和和K数之和是最近听室友提起的几道有意思的基础题,可以说是把双指针运用的淋漓尽致。(K数之和其实是一个动态规划的题,此处因为满足*数之和的的结构,放在一起对比提一下)。 1、两数之和等于Target的下标 LintCode:https://www.lintcode.com/problem/two-sum/ 题目描述:给一个整数数组,找到两个数使得他们的和等于一个给定的数 ...

loongkingwhat的博客 8256

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

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

而双指针做法中,我们利用单调性这个性质,只要这两个数加起来比target大,那我就知道数组中比两个数中较大的数大的那边全都不行,我们花费了O(1)的时间,却得到了O(n)的信息,所以我们可以从O(n²)优化到O(n)。一开始 2 + 9=11小于12,那么不管是2和4,6,8哪个数字加都不可能达到12了,说明左边的选小了(同时也说明2肯定不会是答案了,就把2排除了,在4,6,8,9中选答案)暴力做法中,我们是拿着两个数字加起来和target比一比大小,我们花费了O(1)的时间,得到了O(1)的信息。

m0_74795952的博客 932

两数之和——双指针法

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。 说明: 返回的下标值(index1 和 index2)不是从零开始的。 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 示例: 输入: numbers = [2, 7, 11, 15], target = 9 输出: [1,2] 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, inde

z2431435的博客 2167

经典算法问题2:两数之和、三数之和、四数之和、N数之和

经典算法问题2:两数之和、三数之和、四数之和、N数之和

subtitle_的博客 1653

相向双指针 算法笔记 力扣167.两数之和 - 输入有序数组 力扣35.三数之和 C++

相向双指针的学习 C++实现的题目:力扣167.两数之和 - 输入有序数组 力扣35.三数之和

qq_74450333的博客 2007

双指针算法篇:两数之和 、三数之和

我们依旧使用左右指针的方法,需要先确定一个值,在这里我们用i来表示,nums[i]来做第一个值,每次循环时,使用target=-nums[i]来记录,以上就是两数之和和三数之和的解题思路,至于后面的四数之和,思路也与上面一致 ,先排序,然后依次确定第一,第二,第三,第四个数,并注意去重。当调整完后,如果值与上一个值相同,那么结果也肯定是相同的,所以要跳过相同的值,同时也要注意i的去重。我们先对数组进行排序,这样有利于返回数组的去重工作,因为有序状态下,重复的三元组中的顺序是一样的。

decade777555的博客 1703

两数之和 三数之和 四数之和一网打尽

目录 两数之和: ????思考方式: 两数之和II ????解题图示: 三数之和: 最近的三数之和: 四数之和: 两数之和: 对应letecode链接: https://leetcode-cn.com/problems/two-sum/ 题目描述: 给定一个整数数组 nums和一个整数目标值 target,请你在该数组中找出 和为目标值 target的那两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

qq_56999918的博客 1425

两数之和(双指针)

求n数之和为目标值的所有组合

yzlmhzz的博客 700

从两数之和到n数之和--力扣第一题的联想(c++)

两数之和可谓力扣上非常经典的一道题,对于计算机大牛来说,这道题与1+1=2没有什么区别,对于新手来说,这是对原本陌生算法的第一次亲密接触。自然而然,两数之和衍生出三数之和,四数之和等众多题目,只要我们找到他们之中的本质思想,在加一点点知识储备,这种问题就不足为惧了。注:本文为代码随想录学习笔记,代码部分来源自。

BugMonsterlulu的博客 1097

Lintcode 两数之和 系列

Lintcode 56 两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target。 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1。 样例 给出 numbers = [2, 7, 11, 15], target = 9, 返回 [0, 1]. 分析: 这题目很简单,两数之间已经有了确定的映射关系,直接用......

Bismarckczy的博客 590

代码之旅:我的算法探索之路(一)力扣 两数之和 三数之和问题

我们将采用双指针,因为这样可以避免多重循环,与常规的双指针不同的是,我们将把left设置为循环标志i的后一位,right设置为数组最后一位,然后慢慢向中间移动,因为这样有个很好的好处是我们可以基于现在三个数字的sum之和,来制定哪个指针移动的移动策略。这种写法需要我们时刻理清对字典的操作,我们采用的num值作为字典的键,下标是这个键所存储的值,对于python,我们可以通过in关键字直接查找字典中有没有某个键。:当数组排序后,相同的元素会排列在一起,这让去除重复的三元组变得容易。你可以按任意顺序返回答案。

夏目艾拉的学习之路 1210
上一篇: Leetcode关于单词距离的问题
下一篇: Leetcode关于加法运算的总结
Bert.King
博客等级 码龄15年 280粉丝 151原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值