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

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

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

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

其实,比较著名的就是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. AngularJS 计时器

    <div ng-controller="MyController"> <!--显示$scope.clock的now属性--> <h1>hello ...

  2. 服务器做RAID10

    将接上Raid card的机器开机,根据提示按组合键进入Raid配置界面(一般是按Ctrl+H,具体的根据提示进行即可)   点击Configuration Wizard,选择new configur ...

  3. c# windows程序调用本地输入法

    原文:c# windows程序调用本地输入法    好久没写博客了,今天写了一个DEMO,在WINform程序中调用本地输入法,并在窗体中显示出来.其中使用到了很多API,现把代码贴出来,供大家参考 ...

  4. 利用WIX制作安装包(3)

    原文 利用WIX制作安装包(3) 利用WIX安装服务非常简单.只需要短短几句话就可以.当我们创建好一个Windows服务之后.我们在项目中创建一个Service.wxs 文件来安装服务,并且编辑代码如 ...

  5. 微服务架构之「 下一代微服务 Service Mesh 」

    Service Mesh 被大家称为下一代的微服务,是微服务领域的一颗新星,被大家讨论的非常多. 我在大家的讨论中,还看到有人说 “目前的微服务架构我都没学会呢,现在又来一个下一代微服务,真学不动了” ...

  6. 深入理解Delphi的消息机制(别人写的,简明扼要,用来复习)

    永远记住,无论你是用 SDK 还是借用 VCL 来创建窗口,都要遵循 Windows 的游戏规则,即先注册窗口类,然后再创建窗口实例,在消息循环中写实现代码.你还要知道 Windows 已经为了我们预 ...

  7. winform实现DataGridView全选

    之前写过,一时想不起来就在网上找了一些.结果感觉好麻烦.于是就自己打开之前做过的功能.找到源码. private void CheckDatabasexuan() { DataGridViewChec ...

  8. Win10《芒果TV》商店版更新v3.1.3.0:优化应用速度,支持会员卡兑换

    在微软秋季Win10/Surface新品发布会热潮之后,<芒果TV>UWP版迅速更新v3.1.3版,优化应用启动速度,支持会员卡券兑换,新增全网搜索.记忆播放.消息推送等功能. 芒果TV ...

  9. Java8 的一些新特性总结

    目前Java8已经发布很多个版本了,对于Java8中的新特性虽然有各位大神进行jdk8的英文特性文档翻译,但都太官方化语言,对照几篇翻译本人对新特性文档做一下总结,以帮助我和各位不了解Java8新特性 ...

  10. Tensorflow初级篇

    第二章 Tensorflow主要依赖两个工具:Protocol Buffer和Bazel Protocol. Protocol Buffer是一个结构数据序列化的的工具,在Tensorflow中大部分 ...