DFS手写排列
DFS手写排列
虽然python中有自带的排列函数,但是在某些特殊情况需要手写排列。掌握了DFS手写排列对DFS的理解有一定的帮助。
1.手写排列(非字典序输出)
这种代码比较简单易懂,但是不是按照字典序输出。
思路
拿sta作为起始数和后面每一个数交换,sta+1再与后面的每一个数交换。
例如:1 2 3 4 ,1作为sta和后面的2进行交换变成 2 1 3 4 。
然后sta移动一位,再与后面的数交换。因为第一个数改变了,所以后面的数每次改变的数都和 1 2 3 4 是不同的,也就是新的一种排列。
具体操作写一个dfs()函数每次交换完后,把传进函数里的参数+1(sta移动一位)
def dfs(sta, end):
if sta == end:
print(li[0 : end + 1])
else:
for i in range(sta, end + 1):
li[sta], li[i] = li[i], li[sta]
dfs(sta + 1, end)
li[i], li[sta] = li[sta], li[i]
我们知道每次递归都需要写一个条件来结束递归,代码中的结束条件 sta == end 就代表sta后面已经没有可交换的数了,所以输出结果。
for i in range(sta, end + 1):
li[sta], li[i] = li[i], li[sta]
dfs(sta + 1, end)
li[i], li[sta] = li[sta], li[i]
代码里的这个 for 循环中的 i 就代表sta后面需要交换的数。
交换后完成了输出还要再交换回来。
例如:1 2 3 递归第一层 for 循环 i 可以取到 0、1、2。第一层 i 是0的时候递归到第二层还是 1 2 3 (我的例子只有三个数,递归的第三层就是输出结果)第二层 for 循环的 i 可以取到 1 和 2。i 是 1的时候2是和自己交换,然后输出 1 2 3。i 是 2的时候2是和3换,输出 1 3 2。如果不换回来的话,递归第一层 i 是 1 的时候本来到第二层是 2 1 3,但由于之前没有交换回来,第一层 for 循环 i 是 0 情况的最后一个数 1 3 2 被保留了下来,所以第一层 for 循环 i 是 1 时候的第二层的数就会变成 3 1 2,以至于后面一直出错。我们需要的是每次在 1 2 3 原数中进行交换,所以输出完后要交换回来。
整体代码
代码是 1 2 3 的全排列输出:
def dfs(sta, end):
if sta == end:
print(li[0 : end + 1])
else:
for i in range(sta, end + 1):
li[sta], li[i] = li[i], li[sta]
dfs(sta + 1, end)
li[i], li[sta] = li[sta], li[i]
li = [i for i in range(1, 10)]
dfs(0, 2)
2.手写排列(字典序输出)
这种代码在手写排列中用的很多,输出也是按照字典序输出的。
思路
每次选一个数锁定,锁定的数不能再选,通过循环按顺序找到没被锁定的数添加,最后输出。我们需要定义以下几个列表:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 用来排列
b = [0] * 10 # 用于输出
vis = [False] * 10 # 表示锁定
n = 3 # 需要排列的个数
下面是dfs()函数的定义:
def dfs(s, t):
if s == t:
print(b[0: n])
else:
for i in range(t):
if not vis[i]:
vis[i] = True
b[s] = a[i]
dfs(s+1, t)
vis[i] = False
递归的结束条件是递归深度达到了需要排列的个数。
for 循环每次取一个数,if 语句来判断这个数是否被锁定,如果没有被锁定在 b 列表中添加这个数,递归深度+1,然后继续判断数有没有被锁定。
这个思路有点像用暴力法手写排列组合,不过暴力法是用很多个 for 循环,每一个 for 循环写循环的范围来避免重复,而DFS这种写法是用了一个 vis 列表代表锁定来避免重复。
和上面的情况一样,输出完之后,上了锁的要解锁!
因为每次 for 循环是顺序查找有无上锁,所以输出也是按照字典序输出的。
整体代码
代码是 1 2 3 的全排列按照字典序输出:
def dfs(s, t):
if s == t:
print(b[0: n])
else:
for i in range(t):
if not vis[i]:
vis[i] = True
b[s] = a[i]
dfs(s+1, t)
vis[i] = False
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [0] * 10
vis = [False] * 10
n = 3
dfs(0, n)
var code = “d29a9066-194e-4cb5-bc78-72ecaba56faf”
DFS手写排列的更多相关文章
- dfs手写栈模板
在竞赛中如果系统栈很小的话,过深的递归会让栈溢出,这个时候我们就要自己手写栈,将递归转化成手工栈. 方法其实也很简单. 基本思路上,我们就是用栈不断的pop,push.但是何时push,何时pop呢? ...
- 【OpenCV学习笔记】之六 手写图像旋转函数---万丈高楼平地起
话说,平凡之处显真格,这一点也没错! 比如,对旋转图像进行双线性插值,很简单吧? 可,对我,折腾了大半天,也没有达到预期效果! 尤其是三个误区让我抓瞎好久: 1,坐标旋转公式. 这东西,要用 ...
- 【Machine Learning in Action --2】K-近邻算法构造手写识别系统
为了简单起见,这里构造的系统只能识别数字0到9,需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:宽高是32像素的黑白图像.尽管采用文本格式存储图像不能有效地利用内存空间,但是为了方便理 ...
- k-近邻算法-手写识别系统
手写数字是32x32的黑白图像.为了能使用KNN分类器,我们需要把32x32的二进制图像转换为1x1024 1. 将图像转化为向量 from numpy import * # 导入科学计算包numpy ...
- MLP 之手写数字识别
0. 前言 前面我们利用 LR 模型实现了手写数字识别,但是效果并不好(不到 93% 的正确率). LR 模型从本质上来说还只是一个线性的分类器,只不过在线性变化之后加入了非线性单调递增 sigmoi ...
- hihoCoder 第136周 优化延迟(二分答案+手写堆)
题目1 : 优化延迟 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho编写了一个处理数据包的程序.程序的输入是一个包含N个数据包的序列.每个数据包根据其重要程度不同 ...
- densenet tensorflow 中文汉字手写识别
densenet 中文汉字手写识别,代码如下: import tensorflow as tf import os import random import math import tensorflo ...
- BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset
BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i ...
- 人工智能-深度学习(3)TensorFlow 实战一:手写图片识别
http://gitbook.cn/gitchat/column/59f7e38160c9361563ebea95/topic/59f7e86d60c9361563ebeee5 wiki.jikexu ...
- Tensorflow之MNIST手写数字识别:分类问题(1)
一.MNIST数据集读取 one hot 独热编码独热编码是一种稀疏向量,其中:一个向量设为1,其他元素均设为0.独热编码常用于表示拥有有限个可能值的字符串或标识符优点: 1.将离散特征的取值扩展 ...
随机推荐
- pycharm2019.3.1版本需要的JetBrains Runtime 11不支持windows 32位系统。
提示信息显示安装pycharm2019.3.1版本需要的JetBrains Runtime 11不支持windows 32位系统. 2.更换pycharm社区版的安装版本 百度找到解决办法,参考文章& ...
- NET Core 部署IIS 碰到得问题解决(内托管模式超时、不允许得请求谓词、直接请求无响应、拒绝服务405)
web.config 配置说明 典型的web.confg 配置. 注意其中hostingModel模式和requestTimeout 进程内托管需要注意使用单独的应用程序池: 请求超时默认5分钟,出错 ...
- DOS基本命令与快捷键
DOS命令 #查看当前盘下的所有目录 dir #切换盘符 直接盘符名称: 例如切换D: #切换目录 cd 目录名称 #清屏 cls #退出 exit #创建 cd>文件名称.文件后缀 #查询电脑 ...
- element ui 全选反选
<el-checkbox class="selectAll" :indeterminate="isIndeterminate" v-model=" ...
- Windows 10 输入法(仅桌面) %100 解决
大家好,今天我遇到了一件非常难受的一件事,那就是 WIndows 自带的输入发问题,无法输入中文!!! 这时我去网上找找解决方案,总结了一下几个: 文件检查 步骤 以管理员身份运行PowerShell ...
- <context:component-scan/>和<mvc:annotation-driven/>的区别
1 <context:annotation-config/> 如果你想使用@Autowired注解,那么就必须事先在 spring 容器中声明 AutowiredAnnotationBea ...
- HAL层分析
1. 安卓HAL模块基本 2. 定义hal层代码的5个特性 1)硬件抽象层具有与硬件的密切相关性. 2) 硬件抽象层具有与操作系统无关性. 3) 接口定义的功能应该包含硬件或者系统所需硬件支持的所有功 ...
- Github说明--如何在Github里面上传自己的代码
1.注册一个账号 这是必须的啦!不清楚注册步骤的,可以去看看我之前的博客,里面的步骤也是挺详细的呢! 2.进入到用户主界面 我们会看到这样的一个+标识: 选择其中的New Repository选项,点 ...
- Android笔记--事务处理+数据库版本升级
事务处理 beginTransaction:开始事务的标志 setTransactionSuccessful:事务成功的标志 endTransaction:结束事务的标志 在上面的图片里面,首先进行事 ...
- OVS内核流表查询过程
概括 现在的OVS使用microflow+megaflow缓存查询流表,ovs整体流程是从ovs_vport_receive(datapath/vport.c)开始,然后进入ovs_dp_proces ...