引言
在今天的文章中,我们将解决一个与数组操作相关的经典算法问题——在有序数组中查找和为特定值的两个元素。这个问题通常出现在各种编程竞赛和算法面试中,要求我们在一个已排序的数组中找出两个数,它们的和等于给定的目标值。特别地,我们将使用双指针技巧来高效地解决这个问题,这是一种在处理有序数组时非常有效的策略。
leetcode-找总价格为目标值的两个商品
问题描述
购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回任一结果即可。
示例:
输入: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:暴力法,超时
使用两层循环遍历数组,对每一对元素检查它们的和是否等于目标值。
思路2:碰撞“指针”
由于数组已排序,我们可以使用双指针技巧。一个指针指向数组的起始位置,另一个指针指向数组的末尾位置。
根据两个指针所指向的元素之和与目标值的大小关系,移动左指针或右指针来逼近目标值。
如果和等于目标值,返回这两个元素的索引。
如果和小于目标值,说明需要增加和的值,因此左指针向右移动。
如果和大于目标值,说明需要减小和的值,因此右指针向左移动。
代码实现
以下是使用思路1,C++实现的代码示例(超时) :
class Solution {
public:
vector<int> twoSum(vector<int>& price, int target) {
for(int i=0; i<price.size(); i++){
for(int j=i+1; j<price.size(); j++){
if(price[i]+price[j] == target){
return {price[i] , price[j]};
}
}
}
return {-1,-1};
}
};
以下是使用思路2,C++实现的代码示例:
class Solution {
public:
vector<int> twoSum(vector<int>& price, int target) {
int left = 0 , right = price.size()-1;
while(left < right){
if(price[left] + price[right] < target) left++;
else if(price[left] + price[right] > target) right--;
else return {price[left],price[right]};
}
return {left , right};
}
};