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

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

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

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

其实,比较著名的就是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. 【Struts2学习笔记(3)】至Action注入属性值

    (1)有属性注入? 当一些属性不适合固定写入时适合使用这样的方法,对于一些使用特频繁的类或者方法,非常多类都会用到,那么使用属性注入会节省很多其它的力气.并且在设计的时候就能够提早的把该属性给定义出来 ...

  2. node.js学习笔记之json数据转string

    Node.js中的JSON问题   var str = '{"dir":"kunhony","param":"archive&qu ...

  3. JS里脱离文档流

    <html xmlns="http://www.w3.org/1999/xhtml"><head>    <title></title&g ...

  4. ASP POST请求

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  5. 【C#】wpf添加gif动图支持

    原文:[C#]wpf添加gif动图支持 1.nuget里下载XamlAnimatedGif包,然后安装. 2.添加XamlAnimatedGif包的命名空间:xmlns:gif="https ...

  6. 【转】 C#后台调用前台javascript的五种方法

    第一种,OnClientClick    (vs2003不支持这个方法)<asp:ButtonID="Button1" runat="server" Te ...

  7. Gralde 网络代理

    Gralde 网络代理 Gradle在编译项目的时候,需要下载一些依赖.墙外的网络就需要设置代理了. 设置的方法,见文档: Accessing the web through a HTTP proxy ...

  8. 从零开始学习音视频编程技术(三) 开发环境搭建(Qt4.86手动设置环境,主要就是设置g++和qmake,比较透彻,附下载链接)

    1.先下载安装Qt 我们使用的版本是4.8. 可以自行百度下载也可以从下面的网盘地址下载: Qt库和编译器下载: 链接:http://pan.baidu.com/s/1hrUxLIG 密码:0181 ...

  9. SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database)

    原文:SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容(C ...

  10. 如何计算memcache的容量

    在容量足够的情况下,当然是越大越好,但这样会造成浪费.不考虑这种情况.我们一般的情况是: memcache集群一开始创建会根据存储的数据量与访问量进行容量大小的估算.再算一个20%的冗余. 在网站快速 ...