上一篇说了使用位运算来进行子集输出,这里使用回溯的方法来进行排序。

回溯的思想,我的理解就是:

把解的所有情况转换为树或者图,然后用深度优先的原则来对所有的情况进行遍历解析。

当然,因为问题中会包涵这各种各样的限制条件,我们可以用这些限制条件去减少遍历的分支。

其实,比较著名的就是0-1背包问题,这个背包问题之后再说,这里先看排列组合。

假设我们的数组为[6,7,8],依然使用0来表示当前数字不存在,用1来表示当前数字存在,我们就可以画出这样一个树:

这里使用递归来生成对应的flag标记,重点是backtrack函数:

#include <stdio.h>

int x[] = {6,7,8};   // 需要排列的数组
int y[] = {0,0,0}; // 存放flag标记
int level = 3; // 有3个数字需要进行排列,对应的就需要排3层 void show()
{
for (int i=0; i<level; i++)
{
printf("flag : %d ", y[i]);
}
printf("\n");
} void backtrack (int t)
{
if (t == level) // 当遍历深度等于level的时候,说明遍历完成,得到一组完整的flag标记
show();
else
for (int i=0;i<=1;i++) // 这里先生成0标记,再生成1标记
{
y[t]=i; // 记录当前层是否存在,0存在,1不存在
backtrack(t+1); // 递归遍历下一层,这里可以根据题目限制来判断是否需要继续下一层的遍历,可以减少遍历次数
}
} int main(void)
{
backtrack(0);
return 0;
} 输出结果为:
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

回溯的基本就那么一个思想,那限制条件怎么用呢?

比如,我有10元钱,这里有三个物品,价格分别是8元,5元,2元,10元,

问,这10元钱可以有哪些买法?

这里存在的一个限制就是:总数不能超过10。

#include <stdio.h>

#define TOTAL 10  // 总数最多为10

int x[] = {8,5,2,10};  // 价格
int y[] = {0,0,0,0};
int level = 4; void show()
{
int n=0;
for (int i=0; i<level; i++) // 计算总价格是否超过10
{
n += y[i] * x[i];
}
if (TOTAL < n)
{
return;
}
for (int i=0; i<level; i++) // 这里直接打印符合条件的价格
{
printf("%d ", y[i]*x[i]);
}
printf("\n");
} void backtrack (int t)
{
if (t == level)
show();
else
for (int i=0;i<=1;i++)
{
y[t]=i;
int n = 0;
for (int j=0; j<t; j++) // 这里先计算一下当前价格是多少
{
n = y[j] * x[j];
}
if (TOTAL > n) // 如果当前价格已经超了,就不需要再递归下一层(因为不论下一层是否存在,总价格必然会超),否则继续递归
backtrack(t+1);
}
} int main()
{
backtrack(0);
return 0;
}
结果为:
0 0 0 0
0 0 0 10
0 0 2 0
0 5 0 0
0 5 2 0
8 0 0 0
8 0 2 0

leadcode的Hot100系列--78. 子集--回溯的更多相关文章

  1. leadcode的Hot100系列--78. 子集--位运算

    看一个数组的子集有多少,其实就是排列组合, 比如:[0,1] 对应的子集有:[] [0] [1] [1,1] 这四种. 一般对应有两种方法:位运算 和 回溯. 这里先使用位运算来做. 位运算 一个长度 ...

  2. leadcode的Hot100系列--17. 电话号码的字母组合--回溯的另一种想法的应用

    提交leetcode的时候遇到了问题,一直说访问越界,但仔仔细细检查n多遍,就是检查不出来. 因为我用到了count全局变量,自加一来表明当前数组访问的位置, 后来突然想到,是不是在leetcode在 ...

  3. leadcode的Hot100系列--64. 最小路径和--权值最小的动态规划

    如果这个: leadcode的Hot100系列--62. 不同路径--简单的动态规划 看懂的话,那这题基本上是一样的, 不同点在于: 1.这里每条路径相当于多了一个权值 2.结论不再固定,而是要比较不 ...

  4. [LeetCode] 78. 子集 ☆☆☆(回溯)

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

  5. leadcode的Hot100系列--62. 不同路径--简单的动态规划

    题目比较清晰,简单来说就是: A B C D E F G H I J K L 只能往右或者往下,从A到L,能有几种走法. 这里使用动态规划的方法来做一下. 动态规划最重要的就是动态方程,这里简单说下这 ...

  6. leadcode的Hot100系列--155. 最小栈

    栈:先入后出,后入先出 像电梯一样,先进入电梯的,走到电梯最深处,后进入电梯的,站在电梯门口, 所以电梯打开的时候,后进入的会先走出来,先进入的会后走出来. push,对应入电梯,把数据往里面压 po ...

  7. leadcode的Hot100系列--206. 反转链表

    这里使用两种方式, 一个是直接从头往后遍历 -------> 迭代 一个是从最后一个往前遍历 -----> 递归 迭代 定义三个变量:pPre pNext pNow pPre表示当前节点的 ...

  8. leadcode的Hot100系列--104. 二叉树的最大深度

    依然使用递归思想. 思路: 1.树的深度 = max (左子树深度,右子树深度)+ 1 . ------> 这里的加1是表示自己节点深度为1. 2.如果当前节点为null,则说明它的左右子树深度 ...

  9. leadcode的Hot100系列--226. 翻转二叉树

    这玩意儿基本上还是遍历的那一套, 这里使用先序遍历的方式,直接对左右子树进行对调即可. (虽然看题目的时候,感觉都一样,但真正写出来之后,印象还是深刻了很多) struct TreeNode* inv ...

随机推荐

  1. 早期malloc分配时,如果内存耗尽分配不出来,会直接返回NULL。现在分配不出来,直接抛出异常(可使用nothrow关键字)

    今天和同事review代码时,发现这样的一段代码: Manager * pManager = new Manager(); if(NULL == pManager) { //记录日志 return f ...

  2. php将秒转换为 分:秒 函数

    php将秒转换为 分:秒 函数 /** * 将秒转换为 分:秒 * s int 秒数 */ function s_to_hs($s=0){ //计算分钟 //算法:将秒数除以60,然后下舍入,既得到分 ...

  3. Word Embeddings: Encoding Lexical Semantics

    Word Embeddings: Encoding Lexical Semantics Getting Dense Word Embeddings Word Embeddings in Pytorch ...

  4. 提示Windows Phone IP over USB Transport (IpOverUsbSvc)未运行,如何解决

    原文:提示Windows Phone IP over USB Transport (IpOverUsbSvc)未运行,如何解决 uwp项目在安装测试时提示,"引导"Device&q ...

  5. C#基础加强篇---委托、Lamada表达式和事件(中)

    2.Lamada表达式     C#共有两种匿名函数:匿名方法和Lamada表达式.在2.0之前的C#版本中,创建委托的唯一方法是使用命名方法.C#2.0中引入了匿名方法,匿名方法就是没有名称的方法. ...

  6. Centos重启关机命令

    Linux centos重启命令: 1.reboot   普通重启 2.shutdown -r now 立刻重启(root用户使用) 3.shutdown -r 10 过10分钟自动重启(root用户 ...

  7. 微信小程序把玩(一)Hello WeApp

    原文:微信小程序把玩(一)Hello WeApp 本篇默认已经成功安装微信小程序工具 新建项目 AppID查看公众开发平台设置查看(https://mp.weixin.qq.com) 项目名称随意填写 ...

  8. HTML 滚动条实现

    ##在对应的div中,添加overflow,固定高度为400px<div class="panel-body" style="height: 400px; over ...

  9. Delphi皮肤之 - 图片按钮

    效果如图,支持普通.移上去.按下.弹起.禁用5种状态. unit BmpBtn; interface uses Windows, Messages, SysUtils, Classes, Graphi ...

  10. Python 2, Python 3, Stretch & Buster

    Python 2.7的终止支持时间为2020年,现在已经是2015年了,然而Debian中仍然有大量软件包是基于Python 2的实现.Debian的维护者开始认真讨论淘汰Python 2.开发者Pa ...