关闭

3Sum

136人阅读 评论(0) 收藏 举报
分类:

Given an array S of n integers, are there elements a; b; c in S such that a + b + c = 0? Find all unique
triplets in the array which gives the sum of zero.
Note:
• Elements in a triplet (a; b; c) must be in non-descending order. (ie, a  b  c)
• The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4}.
A solution set is:
(-1, 0, 1)
(-1, -1, 2)
中文:
给定一个包含n个整数的数组S,找到唯一的三联组,让其和等于0.
解答不能重复。
得到的答案必须是非降序排列的。

重复的情况是
如果当前考察的第一个元素与上一次考察的第一个元素相同。
则,跳过这个元素。因为会重复。
然后根据i,j,k的和判断sum是否大于0或者等于0或者小于0
如果当前考察的第二个元素,与上次考察的第二个元素相同。
则,跳过这个元素。
第三个元素,只有这一次考察,所以不用跳过

如果大于0,则说明k要向左移动。
如果移动之后元素相等,则继续移动一次。
如果小于0,则j要向右移动。

class Solution {  
public:  
    vector<vector<int> > threeSum(vector<int> &num) {  
        // Start typing your C/C++ solution below  
        // DO NOT write int main() function 
        //定义一个三元组
        vector<int> triplet;  
        //定义一个三元组的数组result
        vector<vector<int> > result;  
         //对数组进行排序
        sort(num.begin(), num.end());  
        size_t size = num.size();  
        //如果数组的大小小于3,直接返回result
        if (size < 3)  
        {  
            return result;  
        }  
        size_t i, j, k;  //定义i,j,k
        int sum; //定义和sun 

        for (i = 0; i < size-2; i++)  
        {  
            // 如果第一个考察的元素已经大于目标0,则直接返回  
            if (num[i] > 0)  
            {  
                break;  
            }  
            // 首次去重,如果当前元素考察的第一个元素与上一次考察的第一个元素相同,则跳过这次  
            // 必须先判断i>0,否则在i=0时内存违规访问runtime error  
            if (i > 0 && num[i] == num[i-1])  
            {  
                continue;  
            }  

            // 第二个考察元素小于等于第一个考察元素,从当前考察的第一个元素之后开始考察  
            j = i+1;   
            // 第三个考察元素则是从数组末尾开始进行考察  
            k = size - 1;  
            //j=k的时候结束循环
            while (j < k)  
            {  
                sum = num[i] + num[j] + num[k];  
                if (sum == 0)  
                {  
                    // 如果当前元素考察的第二个元素与上一次考察的第二个元素相同,则跳过这次  
                    // 限制的是符合条件的三元组中的第二个元素,这里需要判断j>i+1,以避免与第一个元素比较  
                    if (num[j] == num[j-1] && j > i+1)  
                    {  
                        j = j + 1;  
                        continue;  
                    }  
                    triplet.push_back(num[i]);  // 三元组第一个元素  
                    triplet.push_back(num[j]);  // 三元组第二个元素  
                    triplet.push_back(num[k]);  // 三元组第三个元素  
                    result.push_back(triplet);  
                    triplet.clear();  
                    j++;        // 第二个考察元素移动  
                }  
                else if (sum > 0)    //   
                {  
                    k = k - 1;  
                    // 避免重复计算,当前考察的三元组第三个元素与上一次考察的相等则跳过这个元素,  
                    // 其实这时只是避免考察它,因为如果当前考察元素与上个考察元素相同,  
                    // 下次的求和结果还是大于0。  
                    // 所以其实它不会出现在结果中,只是为了避免下次重复计算和以及判断  
                    // 可以不用判断,只是影响了一点效率,结果正确  
                    if (num[k] == num[k+1])  
                    {  
                        k = k - 1;  
                    }  
                }  
                else  
                {  
                    j = j + 1;  
                    // 避免重复计算,这里的考虑与上面k的考虑原理相同  
                    // 可以不用判断,只是影响了一点效率,结果正确  
                    if (num[j] == num[j-1])  
                    {  
                        j = j + 1;  
                    }  
                }  
            }  

        }  



        return result;  
    }  
};  
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {

        vector<int> triplets;
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        int n=nums.size();
        if(n<3)
        return result;
        int i,j,k;
        for(i=0;i<n;i++)
        {
            if(i>0&&nums[i]==nums[i-1])
            continue;
            j=i+1;
            k=n-1;
            while(j<k)
            {    



                  if((nums[i]+nums[j]+nums[k])==0)
                {    
                    if(j>i+1&&nums[j]==nums[j-1])
                   { 
                       j++;
                       continue;

                   }
                     triplets.push_back(nums[i]);
                     triplets.push_back(nums[j]);
                     triplets.push_back(nums[k]);
                     result.push_back(triplets);
                     triplets.clear();
                     j++;

                }
                else if((nums[i]+nums[j]+nums[k])<0)
                {
                    j++;
                }
                else if((nums[i]+nums[j]+nums[k])>0)
                {
                    k--;
                }

            }

        }
        return result;

    }
};
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:56322次
    • 积分:3124
    • 等级:
    • 排名:第11453名
    • 原创:255篇
    • 转载:1篇
    • 译文:0篇
    • 评论:1条
    最新评论