1.查找总价格为目标值的两个商品
题目链接:LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)

思路图:

由于算法原理很简单,所以这里并没有写出具体逻辑。大家自己推导以下过程就很容易得出代码逻辑。
代码实现:
cpp
class Solution {
public:
vector<int> twoSum(vector<int>& price, int target) {
int left = 0, right = price.size() - 1;
while(left < right) {
int tmp = price[left] + price[right];
if (tmp > target) right--;
else if (tmp == target) return {price[left],price[right]};
else left++;
}
//如果存在 没有==target的情况 或者 只是一个语法限定 防止编译报错
return {0,0};
}
};
时空分析
时间复杂度为O(n),遍历一遍即可。
空间复杂度为O(1)。
2.三数之和
题目链接:LCR 007. 三数之和 - 力扣(LeetCode)

思路图:

题目思路和上到题目查找总价格为目标值的两个商品一样,只不过本题增加了一个去重要求,细节上更复杂
代码实现:
cpp
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> ret;
int i = nums.size() - 1;
for (int i = nums.size() - 1; i >= 2;) {
int left = 0, right = i - 1, c = i;
while (left < right) {
int tmp = nums[left] + nums[right] + nums[c];
if (tmp > 0) {
right--;
} else if (tmp == 0) {
ret.push_back({nums[left], nums[right], nums[c]});
right--, left++;
//去重 + 防越界
while (left < right && nums[right] == nums[right + 1])
right--;
//去重 + 防越界
while (left < right && nums[left] == nums[left - 1])
left++;
} else {
left++;
}
}
i--;
//去重
while (i >= 2 && nums[i] == nums[i + 1]) {
i--;
}
}
return ret;
}
};
时空分析
时间复杂度为O(n^2),两个while循环。
空间复杂度为O(n^2),一个二维数组。
3.四数之和
题目链接:18. 四数之和 - 力扣(LeetCode)

思路图:

思路和三数之和一模一样,只是多固定一端,细节更复杂而已。
代码实现:
cpp
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
vector<vector<int>> ret;
int n = nums.size();
for (int a = 0; a < n -3;) {
for (int b = a + 1; b < n -2;) {
int left = b + 1,right = n - 1;
//防溢出
long long newTarget = (long)target - (long)nums[a] - (long)nums[b];
while (left < right) {
int sum = nums[left] + nums[right];
if(sum > newTarget) right--;
else if(sum < newTarget) left++;
else { //==
ret.push_back({nums[a],nums[b],nums[left],nums[right]});
left++,right--;
//去重
while(left < right && nums[left] == nums[left-1]) left++;
//去重
while(left < right && nums[right] == nums[right+1]) right--;
}
}
b++;
//去重
while(b < n - 2 && nums[b] == nums[b-1]) b++;
}
a++;
//去重
while(a < n - 3 && nums[a] == nums[a-1]) a++;
}
return ret;
}
};
时空分析
时间复杂度为O(n^3)。
空间复杂度为O(n^2)。