当前位置:首页 > 力扣 > 力扣15题三数之和解法(C++双指针算法详解)

力扣15题三数之和解法(C++双指针算法详解)

3个月前 (07-30)

力扣15题三数之和解法(C++双指针算法详解) 力扣题解 三数之和 C++ 双指针 指针 第1张

一、题目解读

力扣15题(三数之和)要求在一个包含n个整数的数组中,找出所有三个数之和为0的组合,且每个组合的元素不能重复。题目考察数组遍历、排序算法双指针技巧的结合,是经典的多指针问题,对时间复杂度优化有较高要求。

二、解题思路

采用“双指针”策略:首先对原数组排序,然后固定第一个数,通过左右指针在剩余区间内寻找和为目标的数对。核心逻辑在于利用排序后的有序性,通过双指针移动减少无效遍历,并跳过重复元素避免结果重复。

三、解题步骤

1. 排序预处理:对输入数组进行升序排序,为后续双指针操作奠定基础。

2. 外层循环固定首元素:遍历数组,每次固定第一个数(需跳过重复值)。

3. 双指针搜索:

○ 初始化左指针为i+1,右指针为数组末尾;

○ 计算当前三数之和,若为0则记录结果,并移动左右指针时需跳过重复元素;

○ 若和小于0,左指针右移扩大和值;若和大于0,右指针左移缩小和值。

4. 循环终止条件:确保左指针始终在右指针左侧,避免重复计算。

四、代码与注释

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        int n = nums.size();
        
        // 1. 排序预处理
        sort(nums.begin(), nums.end());
        
        // 2. 固定首元素遍历
        for (int i = 0; i < n - 2; ++i) {
            // 跳过重复首元素(优化)
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            
            int left = i + 1;     // 左指针
            int right = n - 1;    // 右指针
            int target = -nums[i]; // 目标值(三数和为0,即其余两数和为-target)
            
            // 3. 双指针搜索
            while (left < right) {
                int sum = nums[left] + nums[right];
                if (sum == target) {
                    // 找到有效组合
                    result.push_back({nums[i], nums[left], nums[right]});
                    // 跳过重复的left和right元素
                    while (left < right && nums[left] == nums[left + 1]) ++left;
                    while (left < right && nums[right] == nums[right - 1]) --right;
                    ++left;  // 移动指针
                    --right;
                } else if (sum < target) {
                    ++left;   // 和太小,右移左指针
                } else {
                    --right;  // 和太大,左移右指针
                }
            }
        }
        return result;
    }
};

注释说明:代码中通过排序降低复杂度,双指针动态调整搜索范围,并利用跳过重复元素避免冗余计算,确保结果正确且不重复。

五、总结

该解法通过排序和双指针技术将时间复杂度优化至O(n^2),空间复杂度O(1)。关键在于利用有序数组的特性,通过首元素固定与双指针动态收缩区间,同时结合去重逻辑保证结果唯一性。适用于求解多元素和为定值的问题,是算法面试中的高频考点。



原创内容 转载请注明出处

分享给朋友:

相关文章

力扣35:二分法在搜索插入位置中的运用

力扣35:二分法在搜索插入位置中的运用

有序数组的定位在一个严格递增的数字序列中,每个元素都有其确定的位置。当新元素试图加入时,我们需要回答两个问题:它是否已经存在?如果不存在,它应该插入在哪里?这道题要求我们在O(log n)时间内完成这...

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

题目重解我们面对一个经典背包问题的变体:给定n个物品,每个物品有重量w和价值v,背包容量为V。需要回答两个问题:1) 普通情况下能获得的最大价值;2) 必须恰好装满背包时的最大价值(若无法装满则输出0...

力扣145:递归之美 轻松掌握二叉树后序遍历

力扣145:递归之美 轻松掌握二叉树后序遍历

题目解读二叉树的后序遍历是一种基础且重要的树遍历方式,其遍历顺序为:先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。这种遍历方式特别适合需要先处理子节点再处理父节点的场景,如内存释放...

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

一、题目解读洛谷B3617题要求将输入的八进制字符串转换为十六进制表示。题目需处理大数场景,且对输入合法性有明确限制(长度不超过1000,仅包含0-7字符)。由于八进制与十六进制无法直接转换,需借助十...

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

一、题目解读力扣2846题要求解决一个基于图连通性的操作优化问题。给定一个无向图,包含边权重,以及一系列查询,每个查询询问两点间路径的最小操作次数。题目关键在于高效计算路径上权重分布的统计信息,并转化...

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

一、题目解读洛谷2652题要求对一组扑克牌进行排序,目标是找到最少需要调整的次数,使得所有牌形成同花顺。题目中,扑克牌由花色和数字组成,需先按花色排序,再在同花色内按数字排序。核心难点在于如何处理花色...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。