leetcode15. 三数之和(哈希表unordered_map、双指针)

题目描述:

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

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

例如,给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:

[ [-1, 0, 1], [-1, -1, 2] ]

方法一:哈希表

想法类似于两数之和,在本题中,已知前两个数,查找数组中是否存在-a-b

#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;

class Solution{
public:
    vector<vector<int>> threeSum(vector<int>& nums){
        vector<vector<int>> result;
        if(nums.size() == 0)
            return result;
        sort(nums.begin(), nums.end());  //对数组排序是为了后续去重 
        for(int i=0; i<nums.size(); ++i){
            if(i!=0 && nums[i] == nums[i-1])
                continue;
            unordered_map<int, int> map;
            for(int j=i+1; j<nums.size(); ++j){
                if(map.find(-nums[i]-nums[j]) != map.end()){
                    result.push_back({nums[i], nums[j], -nums[i]-nums[j]});
                    while(j+1 < nums.size() && nums[j] == nums[j+1])
                        j++;
                }
                map.insert({nums[j], j});
            }
        }
        return result;
    }
};

int main(){
    Solution solution;
    vector<int> vec;
    int i;
    do{
        cin>>i;
        vec.push_back(i);
    }while(getchar() != '\n');
    vector<vector<int>> result;
    result = solution.threeSum(vec);
    int rows = result.size();
    int columns = result[0].size();
    for(int i=0; i<rows; ++i)
        for(int j = 0; j<columns; ++j){
            cout<<result[i][j]<<" ";
        }
    cout<<endl;
    return 0;
}

方法一最后两个测试用例没有通过,超出时间限制

 

方法二:双指针法

首先必须对数组排序,排序后才能使用双指针。遍历整个数组,用i指向a所在的位置,然后固定a,用两个指针指向b和c。移动b和c的位置,直至找到a+b+c=0

//双指针 
class Solution{
public:
    vector<vector<int>> threeSum(vector<int>& nums){
        vector<vector<int>> result;
        if(nums.size() == 0)
            return result;
        sort(nums.begin(), nums.end());
        for(int i=0; i<nums.size(); ++i){
            if(i!=0 && nums[i-1]== nums[i]) //去重 
                continue;
            int j = i+1;
            int k = nums.size()-1;
            while(j < k){
                if(nums[i] + nums[j] + nums[k] == 0){
                    result.push_back({nums[i], nums[j], nums[k]});
                    j++;
                    k--;
                    while(j<k && nums[j-1] == nums[j])  //去重 
                        j++;
                    while(j<k && nums[k+1] == nums[k])  //去重 
                        k--;
                }
                else if(nums[i] + nums[j] +nums[k] < 0)
                    j++;
                else
                    k--;
            }
        }
        return result;
    }
};

 

posted @ 2019-06-23 21:37  松花酿酒春水煎茶  阅读(678)  评论(0编辑  收藏  举报