开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情
Day35 2023/02/10
难度:简单
题目
输入一个升序数组 array 和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,返回任意一组即可,如果无法找出这样的数字,返回一个空数组即可。
示例1
输入:[1,2,4,7,11,15],15
返回值:[4,11]
说明:返回[4,11]或者[11,4]都是可以的
示例2
输入:[1,5,11],10
返回值: []
说明:不存在,返回空数组
思路一
根据题目中升序序列的条件,我们可以使用双指针的方法,使用双指针,分别指向数组的首尾元素,然后双指针相向这运动,分别相加每次的两个指针所指的元素,如果等于目标值就找到,如果小于就移动左侧指针,如果大于则移动右侧指针。
具体步骤:
- 准备左右双指针,初始时分别指向数组首尾。
- 相加两个指针所指元素,如果等于目标值则找到所求元素,若大于目标值,左侧指针移动,小于目标值,右侧指针移动。
- 当两个指针相等时,还没有找到,则数组没有满足要求的元素存在。
关键点
- 当相加后小于目标值,说明我们要寻找更大的元素组合,所以要移动左侧指针,使得相加的值变大。
- 当相加后大于目标值,说明我们要寻找更小的元素组合,所以要移动右侧指针,使得相加的值变小。
算法实现
c++代码实现-双指针
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
vector<int> res; //待返回数组
//左右双指针
int left = 0, right = array.size() - 1; //初始化,分别指向首尾元素
//对撞双指针
while(left < right){
//相加等于sum,找到目标
if(array[left] + array[right] == sum){
res.push_back(array[left]);
res.push_back(array[right]);
break;
//和太大,缩小右边
}else if(array[left] + array[right] > sum)
right--;
//和太小,扩大左边
else
left++;
}
return res;
}
};
- 时间复杂度 --- 左右指针一起访问了数组的全部元素,n为数组长度
- 空间复杂度 --- 常数级数组,无额外的辅助空间
总结
- 双指针指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个指针(特殊情况甚至可以多个),两个指针或是同方向访问两个链表、或是同方向访问一个链表(快慢指针)、或是相反方向扫描(对撞指针),从而达到我们需要的目的。