zoukankan      html  css  js  c++  java
  • 刷题39. Combination Sum

    一、题目说明

    题目39. Combination Sum,是从正数列表中选取几个,其和等于目标数的可能组合。任何一个数可以重复取,如candidates = [2,3,6,7], target = 7,结果集合是[ [7], [2,2,3] ]

    如candidates = [2,3,5], target = 8,结果集合是 [ [2,2,2,2], [2,3,3], [3,5] ]

    题目难度是Medium,先思考一下,再来解答。

    二、我的解答

    经过一番思考,这个题目可以通过dfs(树的深度优先遍历)求解,首先我们画一个“树”,反映求解过程。这个图,我就不上了。我的代码:

    #include<iostream>
    #include<vector>
    #include<algorithm>
    using namespace std;
    class Solution{
    	public:
    		void dfs(vector<vector<int>>& res,vector<int>& candidates,vector<int>& path,int begin,int target){
    			if(target==0){
    				res.push_back(path);
    				return;
    			}
    			for(int i=begin;i<candidates.size() && target-candidates[i]>=0;i++){
    				path.push_back(candidates[i]);
    				dfs(res,candidates,path,i,target-candidates[i]);
    				path.pop_back();
    			}
    		}
    		vector<vector<int>> combinationSum(vector<int>& candidates, int target){
    			vector<vector<int>> res;
    			vector<int> path;
    			if(candidates.size()<1){
    				return res;
    			}
    			sort(candidates.begin(),candidates.end());
    			dfs(res,candidates,path,0,target);
    			return res;
    		}
    };
    int main(){
    	Solution s;
    	vector<int> candidates = {2,3,6,7};
    	vector<vector<int>> res = s.combinationSum(candidates,7);
    	cout<<"candidates of {2,3,6,7}"<<"
    ";
    	for(int i=0;i<res.size();i++){
    		vector<int> r = res[i];
    		for(int j=0;j<r.size();j++){
    			cout<<r[j]<<" ";
    		}
    		cout<<"
    ";
    	}
    	
    	cout<<"candidates of {2,3,5}"<<"
    ";
    	candidates = {2,3,5};
    	res = s.combinationSum(candidates,8);
    	for(int i=0;i<res.size();i++){
    		vector<int>r = res[i];
    		for(int j=0;j<r.size();j++){
    			cout<<r[j]<<" ";
    		}
    		cout<<"
    ";
    	}
    	return 0;
    }
    

    性能:

    Runtime: 12 ms, faster than 84.44% of C++ online submissions for Combination Sum.
    Memory Usage: 9.8 MB, less than 58.33% of C++ online submissions for Combination Sum.
    

    一行代码没修改,再次运行:

    Runtime: 4 ms, faster than 99.94% of C++ online submissions for Combination Sum.
    Memory Usage: 9.3 MB, less than 94.44% of C++ online submissions for Combination Sum.
    

    三、优化

    比较搞笑的是,我一行代码没修改,再次提交性能居然大幅提高。厉害了!

    另外的解答思路是DP,这个是网上的,不是我写的。

    用unordered_map<int, vector<vector>> dict;存储数的分解,比如求{2,3,5,7}和是8的:

    dict[2] ={2}

    dict[3] = {3}

    dict[4] = {2,2}

    dict[5] = dict[2] + dict[3] = {2,3}

    dict[6] = {dict[2] + dict[2] + dict[2]},{dict[3]}

    ....

    class Solution {
    public:
        vector<vector<int>> combinationSum(vector<int> &candidates, int target)
        {
            unordered_map<int, vector<vector<int>>> dict;
            for (int i = 1; i <= target; i++)
                for (int it : candidates)
                    if (i == it){
                        dict[i].push_back(vector<int>{ it });
                    }
                    else if (i > it){
                        for (auto ivec : dict[i - it]) {
                            if (it < ivec[ivec.size() - 1]) {
                                continue;
                            }
                            ivec.push_back(it);
    
                            dict[i].push_back(ivec);
                        }
                    }
    
            return dict[target];
        }
    };
    
    所有文章,坚持原创。如有转载,敬请标注出处。
  • 相关阅读:
    Leetcode刷题笔记
    Leetcode刷题笔记
    朋友发来的图片,要制作成身份证复印件,怎么办?
    记录一次MAC连接投影闪屏的问题。
    win10系统 端口查看问题。
    使用Windows命令行reg控制注册表键值
    SVN钩子HOOK设置自动备份,服务本地可以看到所有更新内容。
    报错代码:svn-http status413'requset entity too large
    SVN: Cleanup failed update报错 文件被锁定lock办法,cleanup 失效报错。
    Samba centos7文件共享服务器搭建教程,可以更改任意需求操作配置详解。
  • 原文地址:https://www.cnblogs.com/siweihz/p/12240964.html
Copyright © 2011-2022 走看看