Leetcode第15题 三数和C++解法

排序加hash,O(n^2)复杂度

class Solution {
    
    
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    
    
        int size=nums.size();
        if(size<3)   return {
    
    };
        sort(nums.begin(),nums.end());
        unordered_map<int,int> hashmap;
        for(int p:nums) {
    
    hashmap[p]++;}
        vector<vector<int>> res;
        for(int i=0;i<size-2;++i)
        {
    
    
            if(nums[i]>0)
                break;
            int x=nums[i];
                for(int j=i+1;j<size-1;++j)
                    {
    
    
                        int y=nums[j];
                        int z=-x-y;
                        if(hashmap.find(z)!=hashmap.end())
                            if(z<x||z<y)
                            break;
                            else if((z==0&&hashmap[z]>2)||(z!=0&&z==y&&hashmap[z]>1)||(z!=y)){
    
    
                                res.push_back({
    
    x,y,z});
                                while(j<size-1&&nums[j]==y)
                                    ++j;
                                j--;
                                }
                    }

                    while(i<size-2&&nums[i]==x)
                        ++i;
                    --i;
        }
        return res;
    }
};

再后来我想用左右双指针向中间靠拢,但发现不行,这样如法处理前后互为相反数的情况,这样的情况下,当然还有相邻两个数间隔比较大的特殊情况也无法处理;

while(back-1>front)
{
    
    
    int x=nums[front],y=nums[back];
    int z=-x-y;
    if(hashmap.find(z)!=hashmap.end()&&z<=y&&z>=x)
        if((hashmap[z]>2&&z==y&&z==x&&y==x))
            {
    
    res.push_back({
    
    x,z,y});}
        else if(hashmap[z]>1&&(z==y||z==x))
            {
    
    res.push_back({
    
    x,z,y});}
        else if(z!=x&&z!=y) 
            {
    
    res.push_back({
    
    x,z,y});}               
    if(abs(x)<abs(y))
        while((back-1>front)&&nums[back]==y)
            --back;
    else
            while((back-1>front)&&nums[front]==x)
            ++front;
}

看了下答案,发现原来可以把双指针用到第二层循环里,需要注意的是,每个循环里面都要小心数组越界

class Solution {
    
    
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    
    
        int size=nums.size();
        if(size<3)   return {
    
    };
        sort(nums.begin(),nums.end());
        vector<vector<int>> res;
        int i=0;
        while(i<size-2)
        {
    
    
            if(nums[i]>0)   break;
            int front=i+1,back=size-1,x=nums[i];
            while(front<back)
            {
    
    
                int y=nums[front],z=nums[back];
                if(0==(x+y+z))
                    res.push_back({
    
    x,y,z});
                if(y+z+x>0)
                    while((front<back)&&z==nums[back])
                        --back;
                else
                    while((front<back)&&y==nums[front])
                        ++front;
            }
            while(i<size-2&&nums[i]==x)
                ++i;
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/meixingshi/article/details/113857089