I 题目描述

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。说明:所有数字(包括 target)都是正整数。解集不能包含重复的组合。 示例 1:

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

示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

I 题解

回溯法。回溯法本质上是一种搜索算法;要实现回溯,需要两点:搜索和解空间。 解题方法通常为递归。

回溯算法将解空间看作一定的结构,通常为树形结构,一个解对应于树中的一片树叶。算法从树根(即初始状态出发),尝试所有可能到达的结点。当不能前行时就后退一步或若干步,再从另一个结点开始继续搜索,直到尝试完所有的结点。也可以用走迷宫的方式去理解回溯,设想把你放在一个迷宫里,想要走出迷宫,最直接的办法是什么呢?没错,试。先选一条路走起,走不通就往回退尝试别的路,走不通继续往回退,直到走遍所有的路,并且在走的过程中你可以记录所有能走出迷宫的路线。



最终,

168/168 cases passed (8 ms)。

Your runtime beats 99.75 % of cpp submissions。

Your memory usage beats 98.76 % of cpp submissions (9.1 MB)。

I C++代码

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<vector<int>> res;
        vector <int > tmp;
        backtracking(0,target,candidates,tmp,res);
        return res;
    }
    void backtracking(int i,int target,vector<int>& candidates,vector<int>&tmp,vector<vector<int>>&res){
        if (target < 0)
            return; 
        if(target == 0){
            res.push_back(tmp);
            return;
        }
        for(int j=i; j<candidates.size();j++){
            if(target < candidates[j])
                break;
            tmp.push_back(candidates[j]);
            backtracking(j,target-candidates[j],candidates,tmp,res);
            tmp.pop_back();
 
        }
    }
};

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

示例 2:

输入:
candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]

II 题解

回溯法。

  • 因为每个元素只能用一次,所以递归时需要从下一个元素开始。
  • 因为candidates元素有重复,所以得到的解空间也会有重复,需要去重。

    同一个父节点下不能有重复的叶节点。,所以遇到相同的便跳过。

    if(j>i && candidates[j]==candidates[j-1])

    AC,

    172/172 cases passed (8 ms)Your runtime beats 94.72 % of cpp submissionsYour memory usage beats 93.16 % of cpp submissions (8.9 MB)。

II C++代码

class Solution {
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<vector<int>> res;
        vector<int> tmp;
        backtracking(0,target,candidates,tmp,res);
        return res;
    }
    void backtracking(int i,int target,vector<int>& candidates,vector<int> &tmp,vector<vector<int>> &res){
        if(target < 0)
            return;
        if(target == 0){
            res.push_back(tmp);
            return;
        }
        for(int j=i; j < candidates.size(); j++){
            if(target < candidates[j])
                break;
            if(j>i && candidates[j]==candidates[j-1])
                continue;
            //if(j<candidates.size()-1 && candidates[j+1]==candidates[j])
            //    continue;
            tmp.push_back(candidates[j]);
            backtracking(j+1,target-candidates[j],candidates,tmp,res);
            tmp.pop_back();
        }
    }
};

34,Leetcode 组合总和I,II -C++ 回溯法的更多相关文章

  1. 图解Leetcode组合总和系列——回溯(剪枝优化)+动态规划

    Leetcode组合总和系列--回溯(剪枝优化)+动态规划 组合总和 I 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 ...

  2. 从Leetcode的Combination Sum系列谈起回溯法

    在LeetCode上面有一组非常经典的题型--Combination Sum,从1到4.其实就是类似于给定一个数组和一个整数,然后求数组里面哪几个数的组合相加结果为给定的整数.在这个题型系列中,1.2 ...

  3. [LeetCode]78. 子集(位运算;回溯法待做)

    题目 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3],   [1],   ...

  4. LeetCode 组合总和(dfs)

    题目 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制重 ...

  5. leetcode组合总和 Ⅳ 解题路径

    题目: 关于动态规划类题目的思路如何找在上一篇博客 https://www.cnblogs.com/niuyourou/p/11964842.html 讲的非常清楚了,该博客也成为了了leetcode ...

  6. LeetCode题解-----Majority Element II 摩尔投票法

    题目描述: Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The a ...

  7. (待解决,效率低下)47. Permutations II C++回溯法

    思路是在相似题Permutations的基础上,将结果放到set中,利用set容器不会出现重复元素的特性,得到所需结果 但是利用代码中的/* */部分通过迭代器遍历set将set中的元素放在一个新的v ...

  8. Leetcode之回溯法专题-40. 组合总和 II(Combination Sum II)

    Leetcode之回溯法专题-40. 组合总和 II(Combination Sum II) 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使 ...

  9. Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III)

    Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III) 同类题目: Leetcode之回溯法专题-39. 组合总数(Combination Sum) Lee ...

随机推荐

  1. SAP MM 同一个序列号可以被多次用在交货单发货过账?

    SAP MM 同一个序列号可以被多次用在交货单发货过账? 如下公司间转储订单,从公司代码CSAS转入公司代码HKCS, 物料有启用序列号管理. 转储数量为5 PC.该STO单据共计有2个外向交货单 8 ...

  2. android studio学习----gradle命令详解

    首先来给大家介绍一种简便并且个人最喜欢的一种办法.很多时候我们在GitHub上看到一个不错的开源项目,一般有两种需求,阅读源码和查看运行效果,如果是单纯的查看源码我更喜欢用一些轻量级编辑器,如vim, ...

  3. 修改源代码时不需要重启tomcat服务器

    我们在写JSP + Servlet 的时修改了Java代码就要重新启动服务器.十分麻烦. 为了解决这个问题我们可以将服务器改成debug 模式.就是按调试状态这样修改Java代码就不用再重新启动服务器 ...

  4. 如何在一个ubuntu系统上搭建SVN版本控制工具

    有话说,由于公司项目部署需要,将Windows工程迁移到Linux,通过调查确定使用Ubuntu的Linux操作系统.那么如何快速搭建和Windows一样快捷方便的开发环境就很重要了.本文讲述如何在一 ...

  5. linux epoll,poll,select

    epoll函数用法,还有点poll和select 1,LT的epoll是select和poll函数的改进版. 特点是,读完缓冲区后,如果缓冲区还有内容的话,epoll_wait函数还会返回,直到把缓冲 ...

  6. vue中webpack的配置理解

    当我们需要和后台分离部署的时候,必须配置config/index.js: 用vue-cli 自动构建的目录里面  (环境变量及其基本变量的配置) var path = require('path') ...

  7. P5008 [yLOI2018] 锦鲤抄(Tarjan+贪心)

    洛谷 题意: 给出一个有向图,每次可以删除存在入度的点及其出边,每次删除一个点可以获得其权值. 问最终能够获得的最大权值为多少. 思路: 考虑DAG:我们直接倒着拓扑序来选,即可将所有入度不为\(0\ ...

  8. JS高阶---事件循环模式(事件轮询)

    大纲: 相关知识点: 主体: (1)模型原理 JS部分:初始化代码执行 WebAPIS:执行上下文对象(不是一个真的对象,而是一个抽象的虚拟对象,可以看做栈里的一个区域,包含很多对象) setTime ...

  9. c# 第13节 迭代语句、while、do...while、for、foreach、goto

    本节内容: 1:迭代语句是什么 2:迭代语句之while 3:迭代语句之 do...while 4:迭代语句之for 5:迭代语句之foreach: 6:跳转语句break.continue.retu ...

  10. 201871010112-梁丽珍《面向对象程序设计(java)》第十四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...