leetcode 2 sum & 3 sum & 4 sum

Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

思路:先对数组排序,然后定义两个指针分别指向头尾,看指向的两数之和是否等于目标值,不等则对应向后或向前头尾指针。复杂度O(nlogn+n)=O(nlogn),好于直接枚举O(n^2)。

但是由于返回的是下标值,不能直接排序,将数值和下标组成pair后再排序,这样比较麻烦。

class Solution {
public:
    static bool cmp(pair<int,int> a, pair<int,int> b)
    {
        return a.first < b.first;
    }
    vector<int> twoSum(vector<int>& nums, int target) {
        int len = nums.size();
        vector<pair<int,int>> a;
        vector<int> res;
        for(int i = 0; i < len; i++)
            a.push_back(make_pair(nums[i], i));
        sort(a.begin(),a.end(),cmp);
        int i = 0, j = len - 1;
        while(i<j)
        {
            int tmp = a[i].first + a[j].first;
            if(tmp == target)
            {
                res.push_back(a[i].second);
                res.push_back(a[j].second); 
                break;
            }
            else if(tmp < target)
                i++;
            else
                j--;
        }
        return res;
    }
};

或者采用map,从前向后搜索,记录每个数的下标。对于i,看target-nums[i]是否为map中的key值,如果是说明已找到。

class Solution {
public:
    vector<int> twoSum(vector<int> &numbers, int target) {
        vector<int> ret(2,-1);
        unordered_map<int, int> m;    //value->index map
        for(int i = 0; i < numbers.size(); i ++)
        {
            if(m.find(target-numbers[i]) == m.end())
            //target-numbers[i] not appeared
                m[numbers[i]] = i;
            else
            {
                ret[0] = m[target-numbers[i]]; 
                ret[1] = i;
                return ret;
            }
        }
    }
};

3Sum

在2sum基础上加一层for循环。

class Solution {
public:
    set<vector<int>> S;
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        for(int k=0;k<nums.size();k++)
        {
            int i=k+1;int j=nums.size()-1;
            int target = 0;
            while(i<j)
            {
                int tmp = nums[i]+nums[j]+nums[k];
                if(tmp == target)
                {
                    S.insert({nums[k],nums[i],nums[j]});
                    while(++i<j&&nums[i]==nums[i-1]);
                    while(--j>i&&nums[j]==nums[j+1]);
                }
                else if(tmp < target)
                    i++;
                else
                    j--;
            }
        }
        return vector<vector<int>>(S.begin(),S.end());
    }
};

4Sum

在3Sum基础上再加一层for循环,当然有更好的方法,但是太麻烦了,我懒得去试了。。。

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        set<vector<int>> S;
        sort(nums.begin(), nums.end());
        for(int i = 0; i < int(nums.size()-3); i++)
            for(int j = i + 1; j < int(nums.size()-2); j++)
            {
                int left = j + 1;
                int right = nums.size() - 1;
                while(left < right)
                {
                    int tmp = nums[i] + nums[j] + nums[left] + nums[right];
                    if(tmp == target)
                    {
                        S.insert({nums[i], nums[j], nums[left], nums[right]});
                        while(++left < right && nums[left] == nums[left - 1]);
                        while(--right > left && nums[right] == nums[right + 1]);
                    }
                    else if(tmp < target)
                        left++;
                    else
                        right--;
                }
            }
        return vector<vector<int> > (S.begin(), S.end());
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值