解体思路:需要三个数相加为0,则另外两个数相加应该为上述第一个数的相反数,我们可以利用双指针在剩余的子数组中找有没有这样的数对。
            ···双指针指向剩余子数组的首尾,如果二者相加为目标值,那么可以记录,而且二者中间的数字相加可能还会有   。
就让排好序的数组依次当tag:for(int i = 0; i < n - 2; i++){ 
。。跟哈希的关系在那里?用到了数组哈希去逐个查找元素求和判断等不等于tag?
详细注释
class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {   //返回类型是n和装有符合题目的三元组
        vector<vector<int> > res;
        int n = num.size();
        //不够三元组 fast-template
        if(n < 3)
            return res;                //res为空 没加元素进去
        //排序
        sort(num.begin(), num.end());       //元素排序
        for(int i = 0; i < n - 2; i++){         //假如5个数,n=2的时候下面已经在对 n=3,n=4操作了 否则就越界了
            if(i != 0 && num[i] == num[i - 1])  //i=0是因为&后面要判断num【i-1】,就是从前往后的时候,如果后一个数和当前一样就不用再判断了,直接  continue;下一次循环,而且肯定不是第一次进循环
                continue;
            //后续的收尾双指针
            int left = i + 1;      //那么后一个数和前一个数不一样或者是第一次进循环,摆好对撞指针
            int right = n - 1;
            //设置当前数的负值为目标
            int target = -num[i];
            while(left < right){ //指针不相遇说明没遍历完,直到指针对撞
                //双指针指向的二值相加为目标,则可以与num[i]组成0
                if(num[left] + num[right] == target){  //如果找到目标。开始去重 eg:0,-1-1-1 -2 0 0  0  0 1 1 2 2 2 目标是0找到1和-1一致去重 ,这只是一趟,一趟可能好几个解0-11,0-22针对tag=0的一趟 
                    res.push_back({num[i], num[left], num[right]});//加入-1 1
                    while(left + 1 < right && num[left] == num[left + 1]) //左右分别去重
                        //去重
                        left++;
                    while(right - 1 > left && num[right] == num[right - 1])
                        //去重
                        right--;
                    //双指针向中间收缩 去重后指针新位置开始,left指向-2 right指向0 ,找这一轮的第二个解0-22
                    left++;
                    right--;
                }
                //双指针指向的二值相加大于目标,说明太大了,要变小一点,所以右指针向左   ,注意:右指针只能向左走,左指针只能向右走
                else if(num[left] + num[right] > target)
                    right--;
                //双指针指向的二值相加小于目标,左指针向右
                else left++;
            }
        }
        return res; }
};