双指针系列二--末尾篇(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)。

相关推荐
杜 硕1 小时前
单链表经典算法题
数据结构·算法
汉克老师1 小时前
CSP-J 2026 初赛试题解析(第二部分:阅读程序题(第二题))精讲
c++·csp-j·小学生·学c++编程
神仙别闹1 小时前
基于 C++ 实现(控制台)关键字检索系统
c++
重生之小比特2 小时前
【初阶C++】stack和queue
开发语言·c++·vs·queue
qq_199886872 小时前
第8板块·第1节:主机与设备内存管理基础与统一内存
c++·人工智能·gpu算力·cuda
小O的算法实验室2 小时前
IEEE TCYB,着色旅行商问题:模型、求解与应用
算法
h_a_o777oah2 小时前
【图论】网络流:Dinic 算法模板实现原理及解题技巧
c++·算法·图论·acm·网络流·最小割·dinic算法
千谦阙听2 小时前
【 C++篇】:模板初阶——泛型编程、函数模板与类模板
开发语言·c++·学习·visual studio
我不会起名字3222 小时前
一天一道力扣Hot100(37):深度优先算法--括号生成
java·数据结构·c++·后端·python·算法·go