LeetCode 167. 两数之和 II - 输入有序数组 思考分析

目录

  • 1、暴力,超时
  • 2、双指针+滑动窗口+条件限制 AC
  • 3、观看题解(吸取他人经验)
    • 1、二分查找
    • 2、双指针
    • 3、双指针+二分查找

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:

输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

1、暴力,超时

class Solution {
public:vector<int> twoSum(vector<int>& numbers, int target) {int n = numbers.size();int flag=0;vector<int> res;for(int i=0;i<n;i++){flag=0;for(int j=i+1;j<n;j++){if(numbers[i]+numbers[j]==target){res.emplace_back(i+1);res.emplace_back(j+1);flag=1;break;}}if(flag==1) break;}return res;}
};

2、双指针+滑动窗口+条件限制 AC

在做题提交的过程中发现了几处不容易想到的地方:
1、numbers中的元素是递增的,但是这个递增不是numbers[i]<numbers[i],而是numbers[i]<=numbers[i+1]
2、numbers中的元素有正有负,可能连续好几个都是0
3、一开始我想:首先找到小于等于target的元素个数,这样的话两个值只需要在这些元素中找就可以了,但是事实并非如此。
例如:target=0,numbers[]= {-3,3,.....},如果用numbers[i]<=target,显然只能到第一个元素,所以我又添加了一个限制条件:
(i>=1 && numbers[i-1]+numbers[i]==0)(因为观察的是两个元素相加的结果,所以这样肯定是对的)
所以根据思考之后的修改为:

for(int i=0;i<n;i++)
{if(numbers[i]<=target || numbers[i]==0 ||(i>=1 && numbers[i-1]+numbers[i]==0)){num_smaller_than_target++;}else{break;} 
}

之后只需要在0~num_smaller_than_target-1的范围内寻找两个数就可以了!
然后使用双指针,一开始L指向0,R指向num_smaller_than_target-1,并且保证L<R来循环
在循环过程中,时时注意sum = numbers[L]+numbers[R],
1、如果sum==target,说明我们已经找到值了,直接退出
2、如果sum<target,说明左值一定过小(右边界由于是从大到小缩减的,此时不做改变,因为也不确定右边界是大是小)
3、如果sum>target,说明右值一定过大,选择减少右值(由于左边界是从小到大的,此时不做改变,因为也不确定左边界是大是小)

class Solution {
public:vector<int> twoSum(vector<int>& numbers, int target) {int n = numbers.size();int flag=0;vector<int> res;int num_smaller_than_target=0;//首先找到小于等于target的元素个数for(int i=0;i<n;i++){if(numbers[i]<=target || numbers[i]==0 ||(i>=1 && numbers[i-1]+numbers[i]==0)){num_smaller_than_target++;}else{break;} }int L=0;int R=num_smaller_than_target-1;//两个指针从两边往中间缩while(L<R){int sum = numbers[L]+numbers[R];if(sum==target){res.emplace_back(L+1);res.emplace_back(R+1);break;}//当和小于目标,说明,左值肯定过小else if(sum<target){L++;}//当和大于目标,说明,右值肯定过大else {R--;}}return res;}
};

在这里插入图片描述
因为有要求:
在这里插入图片描述
所以我们来验证一下重复结果是否输出一致:
在这里插入图片描述
显然正确。

3、观看题解(吸取他人经验)

1、二分查找

在数组中找到两个数,使得它们的和等于目标值,可以首先固定第一个数,然后寻找第二个数,第二个数等于目标值减去第一个数的差。利用数组的有序性质,可以通过二分查找的方法寻找第二个数。为了避免重复寻找,在寻找第二个数时,只在第一个数的右侧寻找。

class Solution {
public:vector<int> twoSum(vector<int>& numbers, int target) {int n = numbers.size();int flag=0;for(int i=0;i<n;i++){int low = i+1;int high = n-1;while(low<=high){int mid = (high - low) / 2 + low;if (numbers[mid] == target - numbers[i]) {return {i + 1, mid + 1};}else if (numbers[mid] > target - numbers[i]) {high = mid - 1;} else {low = mid + 1;}}}return {};}
};

在这里插入图片描述
总结:有序序列,查找值固定的数,可以考虑二分查找优化

2、双指针

这是官方题解,和我一开始用的思路是一样的,即双指针。
在这里插入图片描述

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

在这里插入图片描述
而我做的一开始排除一些元素的方法好像没有对时间有很多优化。。。

3、双指针+二分查找

class Solution {
public:vector<int> twoSum(vector<int>& numbers, int target) {int low = 0, high = numbers.size() - 1;while (low <high) {int middle = (low+high)*0.5;//1、目标在middle左侧,重置highif(numbers[low]+numbers[middle]>target){high =middle-1;}//2、目标在middle右侧,重置lowelse if(numbers[high]+numbers[middle]<target){low = middle+1;}//3、重置lowelse if(numbers[low]+numbers[high]<target){low++;}//4、重置highelse if(numbers[low]+numbers[high]>target){high--;}//5、sum等于targetelse{return {low+1,high+1}; }}return {0,0};}
};

在这里插入图片描述
不知道为什么同样的思路,用java速度可以达到1ms,而c++却不行。

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

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

相关文章

敏捷开发用户故事系列之七:用户故事与MVC

这是用户故事系列的第七篇。&#xff08;之一&#xff0c;之二&#xff0c;之三&#xff0c;之四&#xff0c;之五&#xff0c;之六&#xff0c;之七&#xff0c;之八&#xff0c;之九&#xff09;用户故事和MVC没有关系&#xff0c;因为MVC是实现方法&#xff0c;因此在思考用…

七、规则组织的衍生组织——菱形斜纹组织数学模型的建立

基础概念公式推到可参考该专栏下的前几篇博文。 菱形斜纹组织图&#xff1a; 分析&#xff1a;首先3上2下2上1下&#xff0c;飞数为1&#xff0c;右斜。kw8表示从左下角开始往上数8格为纬峰所在位置&#xff1b;kj8表示从左上角开始往右数8格为经峰所在位置。 这样就将菱形斜…

显卡测试软件毛毛虫,超龙超龙,与众不同,顶流配备,散热一流,3070Ti超龙旗舰版评测...

可能大家都没想到此次显卡荒会持续近一年&#xff0c;还是出现国家级干涉才将这股“歪风”刹住了。而且也仅仅算是刹住了大陆的速度&#xff0c;主要踩死刹车的应该就是黄大厨。他从5月初推出的新核心就采取了出厂即锁算力的做法&#xff0c;但是即便如此&#xff0c;那些看着高…

八、非规则组织分析及其数学模型——平纹变化组织

非规则组织顾名思义&#xff0c;无法通过一个数学模型来描述所有的非规则组织、对于每一个具体的非规则组织而言&#xff0c;其也有一定的规律性可循&#xff0c;即可通过分析每一个具体的非规则组织的组织点运动规律来建立相应的数学模型。 一、平纹变化组织 平纹变化组织即…

怎么看xp计算机是32位还是64位,教你查看XP系统的不同32位还是64位详细的步骤

电脑中使用的不同的版本如果安装一些大型的游戏的时候都是有技巧来实现的&#xff0c;那在XP电脑中想要知道的对于不同的32位还是64位的版本的文件操作的时候新手是怎么知道自己安装的软件的版本呢&#xff0c;今天小编就来跟大家分享一下教你查看XP系统的不同32位还是64位详细…

LeetCode 27.移除元素 思考分析

题目 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长…

九、非规则组织分析及其数学模型——曲线斜纹组织

曲线斜纹组织图&#xff1a; 因为其形状酷似抛物线&#xff0c;抛物线又是曲线中的一种&#xff0c;故称为曲线斜纹组织。 特点&#xff1a;1&#xff0c;每一根经纱上的组织点运动规律不变 2&#xff0c;飞数是变化的&#xff0c;故也称为变飞数组织 飞数满足的两个条件&…

计算机公式column,函数公式的左膀右臂:ROW、COLUMN函数知多少

一个公式生成乘法口诀表演示的公式中用到了两个函数&#xff1a;ROW和COLUMN&#xff0c;这两个函数的用途非常广泛&#xff0c;可以配合其他函数实现很多功能(尤其是和VLOOKUP函数)&#xff0c;另外和这两个函数相似的还有ROWS和COLUMNS函数&#xff0c;也顺便介绍下。函数说明…

apache2.4.x三种MPM介绍

三种MPM介绍 Apache 2.X 支持插入式并行处理模块&#xff0c;称为多路处理模块&#xff08;MPM&#xff09;。在编译apache时必须选择也只能选择一个MPM&#xff0c;对类UNIX系统&#xff0c;…

LeetCode 15. 三数之和 思考分析(双指针解)

目录初解&#xff1a;未考虑去重二解&#xff1a;未考虑去重位置三解&#xff1a;AC题目&#xff1a;给你一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;请你找出所有满足条件且…

十、非规则组织分析及其数学模型——锯齿形斜纹组织

锯齿形斜纹组织图&#xff1a; 分析&#xff1a; 前半齿长度k&#xff0c;表示山谷到山峰的列数&#xff0c;也就是锯齿的宽度&#xff1b; 锯齿飞数s&#xff0c;表示山峰到山峰的行数&#xff0c;也就是锯齿的高度。 起始点相差4格&#xff0c;也就是第一部分整体向上移动…

十一、非规则组织分析及其数学模型——芦席斜纹组织

芦席斜纹组织&#xff1a; 该组织是由左斜和右斜有机的结合在一块的&#xff0c;因为其外观酷似芦席故称之为芦席斜纹组织。 织物组织效果&#xff1a; 所需参数&#xff1a; 其基层组织采用双面加强型斜纹&#xff0c;即分子和分母是相同的组织点&#xff0c;例如2上2下(2个经…

LeetCode 18. 四数之和 思考分析(双指针解)

目录需要注意的几点1、去除剪枝操作2、去重操作的细节code以及效果&#xff1a;题目给定一个包含 n 个整数的数组 nums 和一个目标值 target&#xff0c;判断 nums 中是否存在四个元素 a&#xff0c;b&#xff0c;c 和 d &#xff0c;使得 a b c d 的值与 target 相等&#…

图解DotNet框架之一:编译与执行引擎(上)

众所周知,DotNet框架是非常庞大的,光项目创建时的种类就有WPF,WCF,WF这三种最新的技术,还有以前的Web,WinForm,Service,Mobile等等. 这么复杂和庞大的框架,用文字来描述是远远不够的,所以我准备写一系列图文并茂的文章,把我所知道的所有Net框架中的东西全部串联起来,希望可以给…

【Kissy WaterFall】实行手动加载数据

前言&#xff1a;由于Kissy WaterFall默认是监听滚动事件来实现数据动态加载的&#xff0c;但是有一些情况要用到手动加载数据。以下是使用Kissy WaterFall实现手动加载数据的方法。 最终实现效果&#xff1a;点击”逛更多的商店“会动态加载数据 步骤&#xff1a; 当一页数据加…

web服务器文档根目录在哪里,web服务器根目录在哪

web服务器根目录在哪 内容精选换一换SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(访问方式为HTTPS)&#xff0c;实现数据信息在客户端和服务器之间的加密传输&#xff0c;可以防止数据信息的泄露。SSL保证了双方传递信息的安全性&#xff0c;而且用户可以通过…

二、图片加载与保存

一、基本概念 1&#xff0c;什么是图片&#xff1f; 答&#xff1a;图像是结构化存储的数据信息 2&#xff0c;图像的属性 答&#xff1a;1、通道数目&#xff0c;2、宽与高&#xff0c;3、像素数据&#xff0c;4、图像类型 二、加载显示图像并保存 import cv2 import nump…

LeetCode 206. 反转链表 思考分析

题目 反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶: 你可以迭代或递归地反转链表。你能否用两种方法解决这道题&#xff1f; 迭代双指针 从某公众号&#xff08;代码随想录&#xff09;搬过来的gif图&…

怎样看虚拟主机的服务器,虚拟主机怎么查看服务器类型

虚拟主机怎么查看服务器类型 内容精选换一换使用华为云提供的公共镜像制作私有镜像时&#xff0c;您需先购买云主机等云资源时镜像选择公共镜像、云服务器类型建议统一选择“s3 (通用计算型)”&#xff0c;在云主机安装部署完商品&#xff0c;然后参照以下方式进行私有镜像制作…

Anaconda自带Python编译器Jupyter Notebook显示代码行数

ESC&#xff1a;进入命令行模式&#xff1b;按下H即可显示各种快捷键信息 Enter&#xff1a;进入编辑模式 方法一&#xff1a;命令方法 一、点击代码段&#xff0c;按ESC&#xff0c;使代码段显示蓝色&#xff0c;进入命令行模式 二、按下ShiftL&#xff0c;显示代码行数 方法…