前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >组合问题汇总-LeetCode 46、77、39、40、219、377、1014(回溯法,DP,贪心)

组合问题汇总-LeetCode 46、77、39、40、219、377、1014(回溯法,DP,贪心)

作者头像
算法工程师之路
发布2019-12-13 10:16:20
4340
发布2019-12-13 10:16:20
举报

组合问题:LeetCode #46 77 39 40 219 377 1014

1

编程题

回溯法:

  • 递归结束条件
  • 变量状态的改变与恢复(tmp数组)
  • 递归参数中的变量和常量,在循环中变量如何改变!!!

【LeetCode #46】全排列

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]

代码语言:javascript
复制
class Solution {
public:
    vector<vector<int>> res;
    void dfs(vector<int>& nums, int n, int idx){
        if(idx == n){
            res.push_back(nums);
            return;
        }
        for(int i = idx; i < n; i++){
            swap(nums[i], nums[idx]);
            dfs(nums, n, idx+);
            swap(nums[i], nums[idx]);
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        dfs(nums, nums.size(), );
        return res;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/permutations

【LeetCode #77】组合

给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]

代码语言:javascript
复制
class Solution {
public:
    vector<vector<int>> res;
    vector<int> tmp;
    void dfs(int n, int idx, int num){
        if(idx > n+)  return;
        if(tmp.size() == num){
            res.push_back(tmp);
            return;
        }
        for(int i = idx; i <= n; i++){
            tmp.push_back(i);
            dfs(n, i+, num);
            tmp.pop_back();
        }
    }

    vector<vector<int>> combine(int n, int k) {
        dfs(n, , k);
        return res;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combinations

【LeetCode #39】组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。 说明:

所有数字(包括 target)都是正整数。 解集不能包含重复的组合。

示例 1: 输入: candidates = [2,3,6,7], target = 7, 所求解集为: [ [7], [2,2,3] ]

代码语言:javascript
复制
class Solution {
public:
    vector<int> tmp;
    vector<vector<int>> res;
    void dfs(vector<int>& candidates, int target, int start){
        if(target <= ){
            if(target == ){
                res.push_back(tmp);
            }
            return;
        }
        for(int i = start; i < candidates.size(); i++){
            tmp.push_back(candidates[i]);
            dfs(candidates, target-candidates[i], i);
            tmp.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        dfs(candidates, target, );
        return res;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combination-sum

【LeetCode #40】组合总和 II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。

说明: 所有数字(包括目标数)都是正整数。 解集不能包含重复的组合。

示例 1: 输入: candidates = [10,1,2,7,6,1,5], target = 8, 所求解集为: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]

代码语言:javascript
复制
class Solution {
public:
    vector<int> tmp;
    vector<vector<int>> res;
    set<vector<int>> s;    // 去除重复的组合
    void dfs(vector<int>& candidates, int target, int start){
        if(target <= ){
            if(target == ){
                s.insert(tmp);
            }
            return;
        }
        for(int i = start; i < candidates.size(); i++){
            tmp.push_back(candidates[i]);
            dfs(candidates, target-candidates[i], i+);
            tmp.pop_back();
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        dfs(candidates, target, );
        for(auto i: s){
            res.push_back(i);
        }
        return res;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combination-sum-ii

【LeetCode #216】组合总和 III

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明: 所有数字都是正整数。 解集不能包含重复的组合。

示例 1: 输入: k = 3, n = 7 输出: [[1,2,4]]

代码语言:javascript
复制
class Solution {
public:
    vector<int> tmp;
    vector<vector<int>> res;
    void dfs(int k, int n, int start){
        if(n <=  && k == ){   // n与k都有条件限制
            if(n == ){
                res.push_back(tmp);
            }
            return;
        }
        for(int i = start; i < ; i++){
            tmp.push_back(i);
            dfs(k-1, n-i, i+);
            tmp.pop_back();
        }
    }

    vector<vector<int>> combinationSum3(int k, int n) {
        dfs(k, n, );
        return res;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combination-sum-iii

【LeetCode #377】组合求和 IV

给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

示例: nums = [1, 2, 3] target = 4 输出最终为7

代码语言:javascript
复制
class Solution {
public:

    int combinationSum4(vector<int>& nums, int target) {
        if(nums.empty()) return ;
        vector<unsigned long long> dp(target+, );
        dp[] = ;
        for(int i = ; i <= target; i++){
            for(auto j: nums){
                if(i >= j){
                    dp[i] += dp[i-j];
                }
            }
        }
        return dp[target];
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combination-sum-iv/

【LeetCode #1014】最佳观光组合

给定正整数数组 A,A[i] 表示第 i 个观光景点的评分,并且两个景点 i 和 j 之间的距离为 j - i。 一对景点(i < j)组成的观光组合的得分为(A[i] + A[j] + i - j):景点的评分之和减去它们两者之间的距离。

返回一对观光景点能取得的最高分。

示例: 输入:[8,1,5,2,6] 输出:11 解释:i = 0, j = 2, A[i] + A[j] + i - j = 8 + 5 + 0 - 2 = 11

解题思路:

虽然暴力法不能够通过,但可以给我一些贪心算法的思路!通过暴力法中tmp = A[i]+i + A[j]-j可以变换成A[i]+i的最大值与A[j]-j的最大值的求和问题,同时j > i. 因此我们可以使用一个tmp来储存max(A[i]+i), 因为其是旧数据,即i < j.

(暴力法,超时)

代码语言:javascript
复制
class Solution {
public:
    int maxScoreSightseeingPair(vector<int>& A) {
       int tmp = ;
       int res = INT_MIN;
       for(int i = ; i < A.size(); i++){
           for(int j = i+; j < A.size(); j++){
               tmp = A[i] + i + A[j] - j;
               res = max(res, tmp);
           }
       } 
       return res;
    }
};

(贪心法)

代码语言:javascript
复制
class Solution {
public:
    int maxScoreSightseeingPair(vector<int>& A) {
       int tmp = A[] + ;
       int res = INT_MIN;
       for(int i = ; i < A.size(); i++){
           res = max(res, tmp+A[i]-i);
           tmp = max(tmp, A[i]+i);
       } 
       return res;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/best-sightseeing-pair

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法工程师之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档