【LeetCode 16】15.三数之和(双指针法)

简介: 【LeetCode 16】15.三数之和(双指针法)

一、题意

二、思考过程

这道题目使用双指针法 要比哈希法高效一些

首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下标right 在数组结尾的位置上。

依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i] b = nums[left] c = nums[right]。

接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。

如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。

三、完整代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
       vector<vector<int>> result;
       sort(nums.begin(),nums.end());//先对result容器里的数进行一次排序
       //找出a+b+c=0
       //a=nums[i],b=nums[left],c=nums[right]
       for(int i=0;i<nums.size();i++){
           /*
           排序之后如果第一个元素已经大于0,那么无论如何组合都不可能
           凑成三元组,直接返回结果就可以了
           */
           if(nums[i]>0){
               return result;
           }
           /*
           错误去重方法:漏掉[-1,-1,2]的情况
           if(nums[i]==nums[i+1]){
               continue;
           }
           */
           //正确的去重操作:
            if(i>0&&nums[i]==nums[i-1]){//去重操作
                continue;
            }
            int left=i+1;
            int right=nums.size()-1;
            while(right>left){
                if(nums[i]+nums[left]+nums[right]>0){
                    right--;
                }else if(nums[i]+nums[left]+nums[right]<0){
                    left++;
                }else{
                    result.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    //去重逻辑应该放在找到一个三元组之后
                    while(right>left&&nums[right]==nums[right-1])
                        right--;
                    while(right>left&&nums[left]==nums[left+1])
                        left++;
                    //找到答案时,双指针同时缩减
                    right--;
                    left++;
                }
            }
       }
       return result;
    }
};


目录
相关文章
|
4天前
【LeetCode 03】双指针法总结
【LeetCode 03】双指针法总结
10 0
|
4月前
|
存储 算法 数据可视化
【模拟面试问答】深入解析力扣163题:缺失的区间(线性扫描与双指针法详解)
【模拟面试问答】深入解析力扣163题:缺失的区间(线性扫描与双指针法详解)
|
4月前
|
算法 数据挖掘 Java
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
|
4月前
|
存储 算法 数据挖掘
【模拟面试问答】力扣165题:比较版本号(逐个比较与双指针法详解及模拟面试问答)
【模拟面试问答】力扣165题:比较版本号(逐个比较与双指针法详解及模拟面试问答)
|
4月前
|
存储 算法 数据可视化
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
|
4月前
|
存储 算法 大数据
深入解析力扣170题:两数之和 III - 数据结构设计(哈希表与双指针法详解及模拟面试问答)
深入解析力扣170题:两数之和 III - 数据结构设计(哈希表与双指针法详解及模拟面试问答)
LeetCode 680.验证回文字符串 Ⅱ(双指针法)
LeetCode 680.验证回文字符串 Ⅱ(双指针法)
82 0
LeetCode 680.验证回文字符串 Ⅱ(双指针法)
LeetCode 633. 平方数之和(双指针法)
LeetCode 633. 平方数之和(双指针法)
86 0
|
算法
LeetCode 88. 合并两个有序数组(双指针法)
LeetCode 88. 合并两个有序数组(双指针法)
89 0
LEetCode 167. 两数之和 II - 输入有序数组(双指针法)
LEetCode 167. 两数之和 II - 输入有序数组(双指针法)
58 0