• [Leetcode] Combination Sum 系列


    Combination Sum 系列题解

    题目来源:https://leetcode.com/problems/combination-sum/description/


    Description

    Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

    The same repeated number may be chosen from C unlimited number of times.

    Note:

    • All numbers (including target) will be positive integers.
    • The solution set must not contain duplicate combinations.

    Example

    For example, given candidate set [2, 3, 6, 7] and target 7,
    A solution set is:

    [
      [7],
      [2, 2, 3]
    ]
    

    Solution

    class Solution {
    private:
        void backTrack(vector<int>& path, vector<vector<int> >& res,
                       vector<int>& candidates, int begin, int target) {
            if (target == 0) {
                res.push_back(path);
            } else {
                int size = candidates.size();
                if (begin >= size)
                    return;
                for (int i = begin; i < size; i++) {
                    if (candidates[i] <= target) {
                        path.push_back(candidates[i]);
                        backTrack(path, res, candidates, i, target - candidates[i]);
                        path.pop_back();
                    }
                }
            }
        }
    public:
        vector<vector<int> > combinationSum(vector<int>& candidates, int target) {
            vector<vector<int> > res;
            vector<int> path;
            backTrack(path, res, candidates, 0, target);
            return res;
        }
    };
    
    

    解题描述

    这道题类似与经典的零钱兑换问题,在给定的数组candidates,找出所有和为target的数字组合,选择的数字可以重复但解法不能重复。上面使用的是递归回溯的办法,类似DFS,不难理解,下面再多给出使用迭代DP的解法:

    class Solution {
    public:
        vector<vector<int> > combinationSum(vector<int>& candidates, int target) {
            vector<vector<vector<int> > > dp(target + 1, vector<vector<int> >());
            dp[0].push_back(vector<int>());
            for (auto candidate : candidates) {
                for (int j = candidate; j <= target; j++) {
                    if (!dp[j - candidate].empty()) {
                        auto paths = dp[j - candidate];
                        for (auto& path : paths)
                            path.push_back(candidate);
                        dp[j].insert(dp[j].end(), paths.begin(), paths.end());
                    }
                }
            }
            return dp[target];
        }
    };
    
    

    进阶(Combination Sum II)

    进阶版本在第一版的基础上对增加了更多的条件:给出的candidates数组的元素是可以重复的,所以最大问题就是去重,下面给出递归DFS的做法:

    class Solution {
    private:
        int size;
        void dfs(vector<vector<int>>& res, vector<int>& path,
                 vector<int>& candidates, int begin, int target) {
            if (target == 0) {
                res.push_back(path);
            } else if (begin < size) {
                for (int i = begin; i < size; i++) {
                    if (candidates[i] <= target) {
                        if (i > 0 && i > begin && 
                            candidates[i] == candidates[i - 1])
                            continue; //去重的关键过滤步骤:跳过所有相同的元素
                        path.push_back(candidates[i]);
                        dfs(res, path, candidates, 
                            i + 1, target - candidates[i]);
                        path.pop_back();
                    } else {
                        return;
                    }
                }
            }
        }
    public:
        vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
            sort(candidates.begin(), candidates.end());
            this->size = candidates.size();
            vector<vector<int>> res;
            vector<int> path;
            dfs(res, path, candidates, 0, target);
            return res;
        }
    };
    
  • 相关阅读:
    C#学习笔记-类的一些基本成员
    SpringBoot 好“吃”的启动原理
    线程与进程
    powerdesiner
    maven
    Java反射
    获取类的全部信息 本地方法
    今天在看慕课网的java学习路径
    操作系统之哲学原理
    今天在看慕课网的java学习路径
  • 原文地址:https://www.cnblogs.com/yanhewu/p/8414113.html
Copyright © 2020-2023  润新知