文章目录
- 题目链接:
- 题目描述:
- 解法
- C++ 算法代码:
- 图解
题目链接:
LCR 179.查找总价格为目标值的两个商品
题目描述:
解法
解法一(暴力解法,会超时)
两层
for
循环列出所有两个数字的组合,判断是否等于目标值。外层
for
循环依次枚举第一个数a
内层
for
循环依次枚举第二个数b
,让它与a
匹配;我们挑选第二个数的时候,可以不从第一个数开始选,因为a
前面的数我们都已经在之前考虑过了。因此,我们可以从a
往后的数开始列举。然后将挑选的两个数相加,判断是否符合目标值。
解法二(双指针 - 对撞指针)
利用单调性,使用双指针算法解决问题
如果2+21<30
,那么2+7,2+11
等等都不用计算了,因为肯定比2+21
小。
left+right<t
,left
就要往后移动一位。
left+right<t
,left
往后移动一位。
left+right>t
,right
往前移动一位。
left+right==t
,返回结果。
C++ 算法代码:
解法一(暴力解法,会超时)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
for (int i = 0; i < n; i++) { // 第一层循环从前往后列举第一个数
for (int j = i + 1; j < n; j++) { // 第二层循环从 i 位置之后列举第二个数
if (nums[i] + nums[j] == target) // 两个数的和等于目标值,说明我们已经找到结果了
return {nums[i], nums[j]};
}
}
return {-1, -1};
}
};
解法二(双指针 - 对撞指针)
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
int left = 0, right = nums.size() - 1;
while(left < right)
{
int sum = nums[left] + nums[right];
if(sum > target){
right--;
}
else if(sum < target){
left++;
}
else{
return{nums[left], nums[right]};
}
}
// 没有结果就照顾编译器,随便返回个东西。
return {-4941, -1};
}
};
图解
nums=[2,7,11,15,19,21],t=30
-
left=0,right=5
left < right
进入while
循环sum=nums[0] + nums[5]=2+21=23<30
left++;left=1
-
left=1,right=5
left < right
进入while
循环sum=nums[1] + nums[5]=7+21=28<30
left++;left=2
-
left=2,right=5
left < right
进入while
循环sum=nums[2] + nums[5]=11+21=32>30
right--;right=4
-
left=2,right=4
left < right
进入while
循环sum=nums[2] + nums[4]=11+19=30==30
return{11, 19};
-
因为是顺序排列的,所以再次移动得到的不会刚好符合,或者得到的和本次一样,所以程序结束。