??所有算法文章链接(最底部)
目录
在price数组中寻找价值为target的两件商品,返回一个即可,不用考虑重复问题。
利用好数组有序的条件。
两个指针left,right分别指向price数组头和尾部。
如果price[left]+prince[righrt] > target,说明price[right]+最小的值 都比target大,所以price[right]应该被舍去right--。
如果price[left]+prince[righrt] < target,说明price[left]+最大的值 都比target小,所以price[left]应该被舍去left++。
如果price[left]+prince[righrt] =?target,直接返回,prince[left]和price[right]。
class Solution {
public:
vector<int> twoSum(vector<int>& price, int target) {
int i = 0, j = price.size()-1;
while(i < j){
if(price[i] + price[j] == target)
return {price[i],price[j]};
else if(price[i] + price[j] > target) j--;
else i++;
}
return {};
}
};
在nums数组中寻找三个数,这三个数之和为0且下标不相等,这个三元组是不可以重复的
[1,0,-1] [-1,1,0]这两个算重复的三元组。
在暴力枚举的情况下进行优化
先排序数组方便去重
for循环遍历数组,去当前的遍历元素的右区间,寻找两个元素,这两个元素的和是当前遍历元素的相反数。
去右区间寻找两个元素可以用题1的方法。
去重操作
因为数组是排序过的,相同的元素肯定相邻
当nums[i] == -(nums[left]+nums[right])时,left++和right--,直到不和上个元素相同。
当i遍历完当前元素时,i++直到不和上一个元素相同。
例:当前nums[i]== -1,nums[i+1] == -1,为了防止重复i+1位置就不能再遍历,直接i++跳过
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());//排序数组
vector<vector<int>>ans;
int i = 0 , n = nums.size();
for(int i = 0;i < n;){//遍历数组
int target = -nums[i],left = i+1,right = n-1;
while(left < right){//去当前遍历元素的右区间,找和为-num[i]的两个元素
if(nums[left] + nums[right] > target) right--;
else if(nums[left] + nums[right] < target)left++;
else {
ans.push_back({nums[i],nums[left],nums[right]});
left++;
right--;
//右区间内去重//while(left < right && nums[left-1] == nums[left])left++;
while(left < right && nums[right+1] == nums[right])right--;
}
}
i++;
//遍历数组去重//while(i < n && nums[i] == nums[i-1]) i++;
}
return ans;
}
};