【双指针】三数之和

15. 三数之和

给你一个整数数组nums,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != j、i != k且j != k,同时还满足nums[i] + nums[j] + nums[k] == 0。请

你返回所有和为0且不重复的三元组。

注意:答案中不可以包含重复的三元组。



示例 1:

输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]解释:nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]输出:[]解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]输出:[[0,0,0]]解释:唯一可能的三元组和为 0 。


提示:

3 <= nums.length <= 3000

-105<= nums[i] <= 105


解题思路:

(1)最直接的方法就是三个循环,从nums中取三个的全组合。之后在去除收集数据中的重复项,时间复杂度是大于的,这种方法会超时;

(2)第一层优化的想法是:对于重复,可以把整个数组排序,三重循环每次进行的时候判断本次的数是否和上次相同,如此取得的数据满足(a1,a2,a3),一次递增或递减,每次取出来的数据一定是不重复的。

nums[ncount]//nums是有序数组

p1=0;

while (p1

    if (p1==0 || nums[p1]!=nums[p1-1]){

        p2=p1+1;

        while (p2

            if (p2==p1+1 || nums[p2]!=nums[p2-1]){

                p3=p2+1;

                while (p3

                    if (p3==p2+1 || nums[p3]!=nums[p3-1]){

                        ...

                    }

                    ++p3;

                }

            }

            ++p2;

        }

    }

    ++p1;

}

(3)不过这个样子时间复杂度等于,还是会超时。

(4)注意到,当前两层循环的数字确定是,第三重循环里面如果存在则存在唯一一个值满足题意。并且当第二重循环数增大时,第三重循环值一定会比上一次减小,于是可以把后面两重循环的时间复杂度压缩一个等级,通常符合这种情况的数据都适用于双指针

双指针:有序数组中选取两个数,如果当一个数增大时另一个数减小,就可以将的时间复杂度变为


    vector> threeSum(vector& nums) {

        sort(nums.begin(),nums.end());

        vector> res;

        int ncount=nums.size();

        int p1=0;

        while (p1

            if (p1==0 || nums[p1]!=nums[p1-1]){

                int p2=p1+1;

                int p3=ncount-1;

                while (p2

                    if (p2==p1+1 || nums[p2]!=nums[p2-1]){

                        while (p3>p2 && nums[p1]+nums[p2]+nums[p3]>0) {--p3;}

                        if (!(p3>p2)) break;

                        if (nums[p1]+nums[p2]+nums[p3]==0){

                            vector test={nums[p1],nums[p2],nums[p3]};

                            res.push_back(test);

                        }

                    }   

                    ++p2;

                }

            }

            ++p1;

        }

        return res;

    }

你可能感兴趣的:(【双指针】三数之和)