【每日刷题】三数之和

day33, 三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

解答:
第一种方法,排序预处理后,设置两个指针i,j 其中j = i + 1, i 遍历数组,剩下一个元素用二分法查找(此处使用lower_bound)

代码:

vector<vector<int>> threeSum(vector<int>& nums) {
        sort( nums.begin(), nums.end());
        vector<vector<int>> res;
        
        if( nums.size() < 3 || nums[0] > 0 || nums[ nums.size() - 1] < 0)
            return res;
        
        set<vector<int>> result;
        for( int i = 0; i < nums.size(); i++)
            for( int j = i + 1; j < nums.size(); j++){
                
                auto it = lower_bound( nums.begin() + j + 1, nums.end(), 0 - nums[i] - nums[j]) - nums.begin();
                if( it < nums.size() && nums[it] + nums[i] + nums[j] == 0){
                    vector<int> temp{ nums[i], nums[j], nums[it]};
                    sort( temp.begin(), temp.end());
                    result.insert( temp);
                }
                    
            }
        
    
        for( auto it = result.begin(); it!= result.end(); it++)
            res.push_back( *it);
        return res;
    }

运行结果:此处的时间复杂度为O(n^2 logn)
image.png-13.8kB

解答:
方法二:排序预处理后,设置一个指针i 用来遍历,剩下两个元素,设置两个指针j 指向i+ 1, 和 k 指向 size() -1, 这两个指针从两侧向中间移动,寻找符合条件的元素。

代码:

vector<vector<int>> threeSum(vector<int>& nums) {
        sort( nums.begin(), nums.end());
        vector<vector<int>> res;
        
        if( nums.size() < 3 || nums[0] > 0 || nums[ nums.size() - 1] < 0)
            return res;
        
        for( int i = 0; i < nums.size(); i++){
            if( nums[i] > 0)
                break;
            
            if( i > 0 && nums[i] == nums[i-1])
                continue;
            
            int l = i + 1, r = nums.size() - 1;
            while( l < r){
                if( nums[i] + nums[l] + nums[r] == 0){
                    vector<int> temp = { nums[i] , nums[l] , nums[r]};
                    res.push_back( temp);
                    
                    //去重
                    while( l<r && nums[l]==nums[l+1])l++;
                    while( l<r && nums[r]==nums[r-1])r--;
                    
                    l++;
                    r--;
                }
                else if( nums[i] + nums[l] + nums[r] > 0)
                    r--;
                else if( nums[i] + nums[l] + nums[r] < 0)
                    l++;
            }
        }
        
        return res;
    }

运行结果:运行时间O(n^2)
image.png-14.3kB


我的微信公众号

在这里插入图片描述

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页