leetcode 15.三数之和

这是作者在排序的知识点里面找出来的题。但是一开始的时候作者并不知道这东西竟然需要排序操作?后来看清题目要求,说三元组的顺序和输出顺序并不重要的,那么排序倒是可以使用了。

那么为什么要排序呢?一开始读者奔着三重循环去尝试能不能模拟出来。但是时间超时,而且判重的时候需要用到哈希表之类的东西,时间复杂度和空间复杂度太高了。所以就果断放弃了。

后来看了题解才知道,这个题是双指针的用法。而排序就是为了双指针的使用来铺垫的。那么就开始讲讲思路问题。

思路:首先就是需要用sort函数进行排序,之后,就定义两个指针left right。我们用循环来固定一个数nums[i],然后将left放到i+1的位置,将right放到最后一个元素(原因就是由于排序之后,知道了大小关系,所以把指针放到一大一小的位置,方便移动指针),因为需要判断这三个数的和是不是0,所以需要不断地移动指针来实现这种判断。

对三个数的求和,可以转变为两个指针指向的数nums[left]和nums[right]的和与nums][i]之间的大小比较(这在数学上可以说是移项)如果这个时候nums[left]+nums[right]>-nums[i](这里可以用数组元素的大小问题解释为什么需要和nums[i]的相反数比较,因为nums[i]肯定是一个负数。假如说nums[i]是一个大于0的正数,那么这个时候指针指向的数都是大于0的数,就不可能造成三个数的和是0的情况,所以需要和相反数进行比较)那么就是数值开大了,就让right--;反过来,就是让left++,因为这个时候数值开小了。如果相等了,那么这个时候让这一组进入到index容器当中,让left++(因为这个数已经遍历完了,可能后面的数也和这个数相同,也可能不同)。

最后就让index容器中的元素进入到最后的result容器中。

注意:为什么index要用set容器呢?因为这里说了,不能有重复的三元组。而set容器刚好有这种去重的特性。那么有人可能问了,如果三元组{0,0,0}进入之后,是不是三元组里面就只剩下{0}了呢?不会,因为定义的是set>类型,set容器处理的是最外面类型vector容器的去重,不关系到里面容器的去重,而set就会把三元组里面的元素去重。

好了,要讲的点就说完了,那么我们就上代码吧:

class Solution {
public:
    vector> threeSum(vector& nums) {
        int n=nums.size();
        int i,j;
        sort(nums.begin(),nums.end());
        set>index;
        vector>result;
        int left;
        int right;
        for(i=0;i0)
            break;
            int num=nums[i];
            left=i+1;
            right=n-1;
            while(left-num){
                    right--;
                }
                else if(nums[left]+nums[right]<-num)
                left++;
                else{
                    index.insert({nums[i],nums[left],nums[right]});
                    left++;
                }
            }

        }
        for(auto it=index.begin();it!=index.end();it++){
            result.push_back(*it);
        }
        return result;
    }
};

你可能感兴趣的:(leetcode,算法,c++)