Leetcode1.Two Sum+LeetCode15.3Sum+LeetCode18. 4Sum【K-Sum问题】

来源:互联网 发布:淘宝贷款网站 编辑:程序博客网 时间:2024/06/14 17:57

题目链接:https://leetcode.com/problems/two-sum/  (2-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.

Example:

Given nums = [2, 7, 11, 15], target = 9,Because nums[0] + nums[1] = 2 + 7 = 9,return [0, 1].

解题思路:对于2-Sum,笔者提供两种版本(二分 +线性查找),两种版本都是先排序。


线性查找,利用的是一种单调性,比容器盛水那道题(http://blog.csdn.net/u012717411/article/details/53406043)容易理解的多得多,复杂度O(n)。


二分版本O(nlogn)


struct node{    int val,pos;    friend bool operator < (node a,node b){        if(a.val == b.val) return a.pos < b.pos;        return a.val < b.val;    } };class Solution {public:    vector<int> twoSum(vector<int>& nums, int target) {        vector<int>ans;        node p[nums.size()];        for(int i = 0;i < nums.size();++ i){            p[i].val = nums[i];            p[i].pos = i;        }        sort(p,p+nums.size());        bool f = 1;        for(int i = 0;i < nums.size()&&f;++ i){            int l = i+1,r = nums.size();            while(l < r){                int m = (l + r) >> 1;                if(p[m].val == target - p[i].val) {                  ans.push_back(p[i].pos);                  ans.push_back(p[m].pos);                  f = 0;                  break;                }                if(p[m].val < target - p[i].val) l = m+1;                else r = m;            }        }        return ans;    }};


线性查找O(n)


struct node{    int val,id;    friend bool operator <(node a,node b){        if(a.val == b.val) return a.id < b.id;        return a.val < b.val;    }};class Solution {public:    vector<int> twoSum(vector<int>& nums, int target) { //排序O(nlogn) + 查找O(n)        vector<int>ans;        node p[nums.size()];        for(int i = 0;i < nums.size();++ i){            p[i].val = nums[i];            p[i].id = i;        }        sort(p,p+nums.size());        int l = 0,r = nums.size() - 1;        while(l < r){            if(p[l].val + p[r].val == target){                ans.push_back(min(p[l].id,p[r].id));                ans.push_back(max(p[l].id,p[r].id));                break;            }            else if(p[l].val + p[r].val > target) r--;            else l++;        }        return ans;    }};


题目链接:https://leetcode.com/problems/3sum/  (3-sum)


Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: 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]]

解题思路:有了2-sum的求解思路,很容易将3-Sum问题转换成2-Sum。


注意去重的处理,我一开始用二分查找,set去重,结果发现一直TLE;原因就是插入set次数太多,复杂度大于O(n^2log(n))! 


这题必须要O(n^2)的算法才能过,卡set,也附出二分+set的版本:


版本一:二分 + set ( T L E )


class Solution {public:    vector<vector<int>> threeSum(vector<int>& nums) {     set<vector<int>> tar;     sort(nums.begin(),nums.end());     bool f;int l,r;     for(int i = 0;i < nums.size();++ i){         for(int j = i+1;j < nums.size();++ j){             l = j+1,r = nums.size();             f = 0;             while(l < r){                 int m = (l+r) >> 1;                 if(nums[m] == -nums[i]-nums[j]) {f = 1;break;}                 if(nums[m] < -nums[i]-nums[j]) l = m+1;                 else r = m;             }             if(f){                 tar.insert({nums[i],nums[j],-nums[i]-nums[j]});             }          }     }     return vector<vector<int>>(tar.begin(),tar.end());    }};



版本二:不用set,自己剪枝去重即可,注意可能重复的原因(选取的第一个元素重复;两个加数重复;);


用set过不了的,可见这题比较卡时间!


2-Sum问题,用线性查找,总复杂度O(n^2)


class Solution {public:    vector<vector<int>> threeSum(vector<int>& nums) {     vector<vector<int>>ans;     sort(nums.begin(),nums.end());         for(int i = 0;i < nums.size();++ i){        if(i && nums[i] == nums[i-1]) continue;//去重        //if(nums[i] > 0) continue;//剪枝        int tar = -nums[i];        int l = i+1,r = nums.size()-1;        while(l < r){            if(nums[l] + nums[r] == tar){                ans.push_back({nums[i],nums[l],nums[r]});                while(l < r && nums[l] == nums[l+1]) l++;//去重                while(l < r && nums[r] == nums[r-1]) r--;                l++;                r--;            }            else if(nums[l] + nums[r] < tar) l++;            else r--;        }     }    // return vector<vector<int>>(ans.begin(),ans.end());     return ans;    }};


题目链接:https://leetcode.com/problems/4sum/ (4-Sum)


Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note: The solution set must not contain duplicate quadruplets.

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.A solution set is:[  [-1,  0, 0, 1],  [-2, -1, 1, 2],  [-2,  0, 0, 2]]

解题思路:4-Sum转成3-Sum,复杂度O(n^3),注意去重的处理!


参考代码


class Solution {public:    vector<vector<int>> fourSum(vector<int>& nums, int target) {        vector<vector<int>>ans;        sort(nums.begin(),nums.end());        for(int i = 0;i < nums.size();++ i){            if(i && nums[i] == nums[i-1]) continue;//去重            for(int j = i+1;j < nums.size();++ j){                if(j>=i+2 && nums[j] == nums[j-1]) continue;//去重                int l = j+1,r = nums.size() - 1;                while(l < r){                    if(nums[i] + nums[j] + nums[l] + nums[r] == target){                        ans.push_back({nums[i],nums[j],nums[l],nums[r]});                        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[j] + nums[l] + nums[r] < target) l++;                    else r--;                }            }        }        return ans;    }};


K Sum 问题


问题描述


   给你一组N个数字(比如 vector<int> num), 然后给你一个常数(比如 int target) ,我们的目标是在这一堆数里面找到K个数字,使得这K个数字的和等于target;


解题方法


  3-Sum问题转化成2-Sum问题,4-Sum问题转成3-Sum问题,.....,K Sum 问题转换成 K - 1 Sum问题;

  

  2-Sum的求解我们已知,线性查找O(n)。


复杂度

   

  O(n^(k - 1))


1 0
原创粉丝点击