文章目录
- 1.题目
- 2.题目解答
- 1.查找总价格为目标值的两个商品
- 1.1题目及题目解析
- 1.2算法学习
- 暴力解法
- 优化算法
- 1.3代码提交
- 2.三数之和
- 2.1题目及题目解析
- 2.2算法学习
- 2.3代码提交
1.题目
- LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)
- 15. 三数之和 - 力扣(LeetCode)
2.题目解答
1.查找总价格为目标值的两个商品
1.1题目及题目解析
1.2算法学习
暴力解法
这里我们还是先进行暴力解法,根据暴力解法去寻找更好的算法:
直接进行枚举比对即可:
class Solution {
public:
vector<int> twoSum(vector<int>& price, int target) {
vector<int> end;
for(int i =0 ;i<=price.size()-2;i++)
{
for(int j =i+1;j<=price.size()-1;j++)
{
if(price[i]+price[j]==target)
{
end.push_back(price[i]);
end.push_back(price[j]);
}
}
}
end.resize(2);
return end;
}
};
当然这里是过不了的
优化算法
这里因为数组是有序的我们仍然要用指针的方法
先让left
指针指向最左边,让right
指针指向最右边
直接让left
和right
指向的数进行相加和target
进行比较
会出现以下两种情况:
-
left
和right
指向的数比target
小因为数组有序,当
left
不行时,去找比left大的数,直接让left++
-
left
和right
指向的数比target
大此时就不能去移动
left
了,应该让right
向左移动了所以应该是right--
-
将这两部分写成代码如下:
while(left<right) { if(price[left]+price[right]>target) { right--; } else if(price[left]+price[right]<target) { left++; } else { end.push_back(price[left]); end.push_back(price[right]); break; } }
1.3代码提交
全部代码如下:
class Solution {
public:
vector<int> twoSum(vector<int>& price, int target) {
vector<int> end;
int left=0,right = price.size()-1;
while(left<right)
{
if(price[left]+price[right]>target)
{
right--;
}
else if(price[left]+price[right]<target)
{
left++;
}
else
{
end.push_back(price[left]);
end.push_back(price[right]);
break;
}
}
return end;
}
};
2.三数之和
2.1题目及题目解析
2.2算法学习
这里有两种解法:
- 解法一:排序+暴力枚举+利用
set
去重 - 解法二:排序+双指针
这里我们主要演示第二章解法,并且不用set
去重:
首先先选择一个固定数,此时就会发现一个数学关系:
当剩下的两个数为固定数的相反数时,就会成立
所以后面就变成了和前一题一样的解法:找两个数的和
如图:
但是这里仍然有个问题:
如何去重?
这里有两种解决方法:
- 直接用容器去解决(这里我们就不在使用了)
- 找到第一个结果,可以让left和right跳过重复元素,同时固定的数字也要跳过重复元素,但是这里在用循环+/-时一定要注意不要越界访问
2.3代码提交
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> vv;
vector<int> v;
sort(nums.begin(), nums.end());
int i = 0;
while (i < nums.size()) {
if(nums[i]>0)
{
break;
}
int left = i + 1;
int right = nums.size() - 1;
while (left < right)
{
if (nums[left] + nums[right] > (-nums[i]))
{
right--;
}
else if (nums[left] + nums[right] < (-nums[i]))
{
left++;
}
else
{
v.push_back(nums[i]);
v.push_back(nums[left]);
v.push_back(nums[right]);
vv.push_back(v);
v.clear();
left++,right--;//这里先进行++/--
while (left<right && nums[left] == nums[left - 1]) //这里比较就要-1
{
left++;
}
while (right>left && nums[right] == nums[right + 1])
{
right--;
}
}
}
i++;
while ( i < nums.size()&&nums[i] == nums[i - 1]) {
i++;
}
}
return vv;
}
};