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.将离散特征的取值扩展 ...
随机推荐
- jmeter 数据库连接
位置:右击添加>配置元件>JDBC Connection Configuration 作用:需要对数据库发起请求查询数据或者对数据库施加压力 3.设置说明 Variable Name(变量 ...
- vscode配置c++环境(超简单)
vscode配置c++环境(超简单) 超简单!!! 配置c++最麻烦的就是mingw的环境,有很多不同的版本,很杂乱,这里我们用最简单的办法展示. 下载一个devc++. 如果你问我,为什么下了dev ...
- c# datagridview列宽自适应设置
- DOS基本命令与快捷键
DOS命令 #查看当前盘下的所有目录 dir #切换盘符 直接盘符名称: 例如切换D: #切换目录 cd 目录名称 #清屏 cls #退出 exit #创建 cd>文件名称.文件后缀 #查询电脑 ...
- SqlServer提示对象名无效
执行脚本 exec sp_msforeachtable "sp_changeobjectowner '?','dbo'"
- uni-app微信小程序解决多个视频同时播放问题
这里我用的uni-app开发的小程序,微信小程序原生开发也是同理, 写法和api简单改下就行 当你的页面上有多个视频video组件标签时, 会出现多个视频可以同时播放的问题,这样显然是不正常的, 那么 ...
- 表单笔记-Antd(Form)
antd表单使用笔记 import React, { useState, useEffect, useRef } from "react"; import { Form, Inpu ...
- You need to run build with JDK or have tools.jar on the classpath.If this occures during eclipse build make sure you run eclipse under JDK as well 错误
我打开项目报错是这样的 pom.xml jdk配置什么的都是好的 但是还是报错 解决错误 : 1.打开你eclipse的根目录,找到eclipse.ini 这个文件夹打开 2.打开是这个样子 ...
- egret 图片跨域
//图片跨域 egret.ImageLoader.crossOrigin = "anonymous";
- final修饰的作用
在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量) 1.final修饰类 当用final修饰一个类时,表明这个类不能被继承. final类中的成员变量可以根据需要设为f ...