leetcode 2 sum & 3 sum & 4 sum

来源:互联网 发布:佛教电影知乎 编辑:程序博客网 时间:2024/04/19 13:42

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());    }};


原创粉丝点击