DFS算法模板-排列组合-python
DFS算法模板:
def dfs(array or root, cur_layer, path, result):if cur_layer == len(array) or not root:result.append(path)returnfor i in range(cur_layer, len(array)):do something with array[cur_layer:i+1] or nodes with this layerpath.append(xxx) # 修改path 或者 其他操作dfs(array, i + 1 or cur_layer + 1, path, result)path.pop() # 还原path 或者 还原之前的操作
排列组合是组合学最基本的概念。所谓排列,就是指从给定个数的元素中取出指定个数的元素进行排序。组合则是指从给定个数的元素中仅仅取出指定个数的元素,不考虑排序。
https://baike.baidu.com/item/排列组合/706498
(一)组合
//组合
def recursive_c(cur, m, cur_list, original_list, result_list):if m == 0:result_list.append(list(cur_list))returnfor i in range(cur, len(original_list)):cur_list.append(original_list[i])recursive_c(i + 1, m - 1, cur_list, original_list, result_list)cur_list.pop()>>original_list = [1, 2, 3, 4]
>>result_list =[[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
>>共4种
【 题目描述】给定一个数组 num (整数)和一个整数 target. 找到 num 中所有的数字之和为 target 的组合.
原文链接:https://blog.csdn.net/qq_19446965/article/details/81775702
/查找和为target的所有组合,DFS法
def dfs(cur, sum, target, path_list, original_list, result_list):if sum == target:result_list.append(list(path_list))returnif sum > target:returnfor i in range(cur, len(original_list)):path_list.append(original_list[i])dfs(i + 1, sum + original_list[i], target, path_list, original_list, result_list)path_list.pop()
【题目描述】给定一个数组 num 和一个整数 target. 找到 num 中所有的数字(不重复)之和为 target 的组合.
原文链接:https://www.jiuzhang.com/solutions/combination-sum-ii/
注意:if i > 0 and original_list[i] == original_list[i-1]:
def dfs(cur, sum, target, path_list, original_list, result_list):if target == sum:result_list.append(path_list)returnif sum > target:returnfor i in range(cur, len(original_list)):if i > 0 and original_list[i] == original_list[i-1]:continuedfs(i + 1, sum + original_list[i], target, path_list + [original_list[i]], original_list, result_list)
【题目描述】给定一个数组 num 和一个整数 target. 找到 num 中所有的数字之和为 target 的组合(不重复).
https://www.jiuzhang.com/solutions/combination-sum-ii/
注意:if i > cur and original_list[i] == original_list[i-1]:
def dfs(cur, sum, target, path_list, original_list, result_list):if target == sum:result_list.append(path_list)returnif sum > target:returnfor i in range(cur, len(original_list)):if i > cur and original_list[i] == original_list[i-1]:continuedfs(i + 1, sum + original_list[i], target, path_list + [original_list[i]], original_list, result_list)
【题目描述】
给定一个候选数字的集合 candidates 和一个目标值 target. 找到 candidates 中所有的和为 target 的组合.
在同一个组合中, candidates 中的某个数字不限次数地出现.
https://www.jiuzhang.com/solutions/combination-sum/
分析:
Combination Sum 一个数可以选很多次,搜索时从 index 开始而不是从 index + 1
dfs(candidates, index, target - candidates[index], combination, results);
(二)排列
问题模型:求出所有满足条件的“排列”。
判断条件:组合中的元素是顺序“相关”的。
时间复杂度:与 n! 相关。
//全排列
def recursive_a(m, cur_list, original_list, result_list):if m == 0:result_list.append(list(cur_list))returnfor i in range(len(original_list)):cur_list.append(original_list[i])temp_list = deepcopy(original_list)temp_list.pop(i)recursive_a(m - 1, cur_list, temp_list, result_list)cur_list.pop()>>original_list = [1, 2, 3, 4]
>>result_list = [[1, 2, 3], [1, 2, 4], [1, 3, 2], [1, 3, 4], [1, 4, 2], [1, 4, 3], [2, 1, 3], [2, 1, 4], [2, 3, 1], [2, 3, 4], [2, 4, 1], [2, 4, 3], [3, 1, 2], [3, 1, 4], [3, 2, 1], [3, 2, 4], [3, 4, 1], [3, 4, 2], [4, 1, 2], [4, 1, 3], [4, 2, 1], [4, 2, 3], [4, 3, 1], [4, 3, 2]]
>>共24种
https://blog.csdn.net/qq_19446965/article/details/102463792
【题目】给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations-ii
方法一:先生成再去重
def helper(self, nums, res, path):if not nums and path not in res:res.append(path)else:for i in range(len(nums)):self.helper(nums[:i] + nums[i+1:], res, path + [nums[i]])
耗时:1356 ms
这样的做法是在每个path生成之后才去做的判断,因此效率一点都不高。
方法二:深度拷贝
def helper(self, nums, res, path):if not nums and path not in res:res.append(list(path))returnfor i in range(len(nums)):path.append(nums[i])temp_list = deepcopy(nums)temp_list.pop(i)self.helper(temp_list, res, path)path.pop()
耗时:超时
方法三:回溯法
下面这个做法是标准的回溯法,需要用到visited来表示哪些位置已经被添加到path中了。
为什么有重复?
在这个例子中,我们在第一个1开始的排列中已经取了第二个1的情况;如果在第二个1开始的排列中仍然取第一个1,就有重复了。
如何去重呢?
1)排序
2)不是第一个数字,并且现在的数字和前面的数字相等,同时前面的数字还没有访问过,我们是不能搜索的,需要直接返回。
原因是,这种情况下,必须是由前面搜索到现在的这个位置,而不能是由现在的位置向前面搜索。
def helper(self, nums, res, val, visit):if len(val) == len(nums) :res.append(val)for i in range(len(nums)):if i > 0 and not visit[i - 1] and nums[i - 1] == nums[i]:continueif not visit[i]:visit[i] = Trueself.helper(nums, res, val+[nums[i]], visit)visit[i] = False
耗时:56 ms
方法四:交换思想
def swap(nums, i, cur):nums[cur], nums[i] = nums[i], nums[cur]def helper_1(cur, nums, res):if cur == len(nums):res.append(list(nums))for i in range(cur, len(nums)):if nums[i] not in nums[i+1:]:swap(nums, i, cur)helper(cur + 1, nums, res)swap(nums, i, cur)
耗时:44 ms
DFS算法模板-排列组合-python相关推荐
- [算法] 求排列组合: 从n个数中任选m个数组成一个新数
#include <iostream> #include <vector>using namespace std;// 求排列组合算法: C(n, m): 从n个数中任选m个数 ...
- 算法题-排列组合问题
27.Algorithm Gossip: 排列组合 说明 将一组数字.字母或符号进行排列,以得到不同的组合顺序,例如1 2 3这三个数的排列组合有:1 2 3.1 3 2.2 1 3.2 3 1.3 ...
- 程序员必备算法,排列组合
还记得排列组合吗? 在高中的时候最常接触的莫过于排列组合了,毕竟高考必考的嘛.我们先来回忆下这两个的公式是啥: 排列组合公式 如果看到这个还有一丢丢的印象,说明大家的基础都还不错.那么问题来了,大家都 ...
- 算法笔记 --- 排列组合
排列组合的计算公式 转载于:https://www.cnblogs.com/zhongzhiqiang/p/5809116.html
- C++经典算法题-排列组合
27.Algorithm Gossip: 排列组合 说明 将一组数字.字母或符号进行排列,以得到不同的组合顺序,例如1 2 3这三个数的排列组合有: 1 2 3.1 3 2.2 1 3.2 3 1.3 ...
- 数学和算法之---排列组合
本文大部分内容摘自网络只是本人稍加整理分享,供大家学习交流. 排列的概念 从n个不同的元素中,任取m(m<=n)个元素按照一定的顺寻排成一列,叫做从n个不同元素中取出m个元素的一个排列.从n个不 ...
- 必知C++算法之排列组合基本操作
概率组合题目分类 1.高中数学为基础的古典概率计算方法 2.斐波那契数列和卡特兰数 6x9的方格,从左上角到右下角,每次只能向下或向右,一共多少种不同走法 一共13步,五步向下,剩下8步向右 组合问题 ...
- DFS算法走迷宫(python实现)
从@走到!31*31的迷宫 map = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
- 算法 64式 17、排列组合算法整理
1算法思想 排列组合 1.1含义 排列: 含义:从元素列表中取出指定个数的元素进行排序 公式:从n个不同元素中取出m个元素的排列个数=n!/(n-m)! 组合: 含义:从元素列表中取出指定个数的元素, ...
最新文章
- Jumony入门(二)初识选择器
- TrojanDownloader简单分析
- AngularJS(6)-选择框Select
- 也说春运网络购票:12306的码农没有你想的那么弱 [转]
- EXE.DLL文件图标导出器[免费下载]
- idea中artifacts、facets、modules是什么意思?
- python文本文档_Python3 File
- oracle数据库激活控制文件位置,Oracle数据库之Oracle 重建控制文件一例
- c语言sqart函数格式,2019-07-29 复习C语言入门知识
- Kafka 启动报错 AccessDeniedException
- idea 自动同步文件本地内容设置
- IRT模型估计-EM算法
- 【软件测试面试】测试开发一面面试题+回答,大伙感受下强度咋样......
- css小鸡破壳,小鸡出壳是小鸡自己破壳,还是鸡妈妈帮助破壳?
- 【原创】Syncthing搭建自己的中继服务和发现服务
- echart 报表统计
- 百度地图调用加载显示Marker,并添加点击事件
- javaweb JSP JAVA旅游网站在线旅游信息网站(旅游系统旅游网站)jsp旅游管理系统
- 每日一句:day01——From Zero To Hero
- labview csv文件处理_LabVIEW程序写完后,你知道怎样保护你的源代码隐私吗?
热门文章
- Qt tabwidget 标签页设置tabbar标题,tabwidget设置透明色
- C++ 随记三 (一些杂项)
- 小学生C++编程基础 课程8(B)
- turtle 里都write() 可以选择的字体有哪些
- python语言input和if else的嵌套使用_Python中if语句嵌套的方法
- 长期戴耳机的危害有多大?有没有不伤耳朵的蓝牙耳机?
- JQuery在线截取图片
- JavaSE进阶 | import、访问控制权限、Object、匿名内部类
- 老赖的未来生活,竟然是这样!
- 帆软 - ²平方号,€欧元符号 显示乱码