15. 3Sum

Problem

leetcode链接problem

Code

先上我的这超时的破代码,思想是把情况分成了3种,正正负,正负负,正负零,以及000的特例。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        vector<vector<int>> result0 = {};
        vector<int> positive;
        vector<int> negitive;
        vector<int> zero;
        
        if(nums.size() <= 2)
        {
            return result0;
        }

        //sort(nums.begin(), nums.end());
        for(vector<int>::iterator it=nums.begin();it!=nums.end();it++)
        {
            if(*it > 0){
                positive.push_back(*it);
            }
            else if(*it < 0){
                negitive.push_back(*it);
            }
            else{
                zero.push_back(*it);
            }
        }
        sort(positive.begin(), positive.end());
        sort(negitive.begin(), negitive.end());

        if(zero.size() >= 3){
            vector<int> temp = {0,0,0};
            result.push_back(temp);
        }

        for(int i=0;i<positive.size();i++)
        {
            for(int j=0;j<negitive.size();j++){
                for(int k=0;k<zero.size();k++){
                    if(positive[i] + negitive[j] + zero[k] == 0){
                        vector<int> temp = {positive[i],negitive[j],zero[k]};
                        int label = 0;
                        if(result.size() > 0){
                            for(int z=0;z<=result.size()-1;z++){
                                if(temp == result[z]) label = 1;

                            }
                            if(!label)
                            {
                                result.push_back(temp);
                            }

                        }
                        else{
                            result.push_back(temp);
                        }

                    }
                }
            }
        }

        for(int i=0;i<positive.size();i++)
        {
            for(int j=0;j<negitive.size();j++){
                for(int k=0;k<negitive.size();k++){
                    if(j == k)
                    {
                        break;
                    }
                    if(positive[i] + negitive[j] + negitive[k] == 0){

                        vector<int> temp = {positive[i],negitive[j],negitive[k]};
                        int label = 0;
                        if(result.size() > 0){
                            for(int z=0;z<=result.size()-1;z++){
                                if(temp == result[z]) label = 1;

                            }
                            if(!label)
                            {
                                result.push_back(temp);
                            }

                        }
                        else{
                            result.push_back(temp);
                        }
                    }
                }
            }
        }
        for(int i=0;i<positive.size();i++)
        {
            for(int j=0;j<negitive.size();j++){
                for(int k=0;k<positive.size();k++){
                    if(i == k)
                    {
                        break;
                    }
                    if(positive[i] + negitive[j] + positive[k] == 0){
                        vector<int> temp = {positive[i],negitive[j],positive[k]};
                        int label = 0;
                        if(result.size() > 0){
                            for(int z=0;z<=result.size()-1;z++){
                                if(temp == result[z]) label = 1;

                            }
                            if(!label)
                            {
                                result.push_back(temp);
                            }

                        }
                        else{
                            result.push_back(temp);
                        }
                    }
                }
            }
        }

        return result;
    }
};

倒数第三个样例超时了,设计上确实有问题,里面包含了很大部分的重复计算。故网上找答案。
其实我总觉得我这个写法比直接三次循环还要low,感觉有点复杂,关键问题是,还要处理掉重复的情况。
一下答案室友倒是昨天跟我提了一句。降维度,先算两个数,然后在加第三个数。
一下算法就设计的很好,其实跟11题的水桶问题有点相似,就是排序以后从两边推进。

class Solution{
public:
    vector< vector<int> > threeSum(vector<int> &num) {
        vector<int> numSet(3);
        vector< vector<int> > r;
        // 1.排序
        sort(num.begin(), num.end());
        int sum;
        int len = num.size();
        // 2.拿出第一个数,转化为两数和问题。注意外层循环到倒数第三个数即可
        for(int i = 0; i < len-2; i++) {
            sum = 0 - num[i];
            numSet[0] = num[i];
            // 3.两数和问题
            for(int j = i+1, k = len-1; j < k;) {
                if(num[j] + num[k] == sum) {
                    numSet[1] = num[j++];
                    numSet[2] = num[k--];
                    r.push_back(numSet);
                    // 根据题目要求,跳过重复元素
                    while(j < k && num[j] == num[j-1]) 
                        j++;
                    while(j < k && num[k] == num[k+1])
                        k--;
                }
                else if(num[j] + num[k] < sum)
                    j++;
                else 
                    k--;
            }
            while(i < len-2 && num[i+1] == num[i])
                i++;
        }
        return r;
    }
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 题目描述 给定一个整数列表,请问能否从中找出所有满足a + b + c = 0的三元组?例如,给定[-1, 0, ...
    Ricolove阅读 1,821评论 0 0
  • 说好的周更两篇,人的惰性真是可怕,周末瘫床上就什么都不想动了,挣扎着还是坚持上来更新一篇吧,虽然没人看。 Prob...
    假装文艺青年的猥琐大叔阅读 365评论 0 0
  • 题目: 解析: 简单来说,就是三个数相加等于0,找出所有的无重复的组合。 思路: 开始想的很简单,先把所有的的都找...
    夏臻Rock阅读 472评论 0 0
  • https://leetcode.windliang.cc/ 第一时间发布 题目描述(中等难度) 解法一 暴力解法...
    windliang阅读 228评论 0 0
  • Description: Given an array nums of n integers, are there...
    Ysgc阅读 368评论 0 0