双指针系列二--末尾篇(3道题)

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)。

相关推荐
文丑颜不良啊38 分钟前
LeetCode1461~1480题目解析
java·leetcode
Sakura_j_h_9 小时前
EasyEDA PCB 快速设计Skills
c++·python·github
ZhengEnCi9 小时前
Agent 架构怎么选:从单 Agent 到多 Agent 编排的选型决策指南
算法·架构
程序喵大人10 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
秋天的怀念_David10 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Pniubi10 小时前
力扣283移动零(双指针法)
算法·leetcode·职场和发展
hhb_61811 小时前
大模型落地三重优化实战
人工智能·算法·机器学习
云和数据.ChenGuang11 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
jimy112 小时前
C++ 中的 `T&&`:右值引用与转发引用
开发语言·c++
2601_9707038312 小时前
工业除湿机租赁:把一份租金合同拆开看
大数据·数据结构·算法·数据库架构·推荐算法