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相关推荐

  1. [算法] 求排列组合: 从n个数中任选m个数组成一个新数

    #include <iostream> #include <vector>using namespace std;// 求排列组合算法: C(n, m): 从n个数中任选m个数 ...

  2. 算法题-排列组合问题

    27.Algorithm Gossip: 排列组合 说明 将一组数字.字母或符号进行排列,以得到不同的组合顺序,例如1 2 3这三个数的排列组合有:1 2 3.1 3 2.2 1 3.2 3 1.3 ...

  3. 程序员必备算法,排列组合

    还记得排列组合吗? 在高中的时候最常接触的莫过于排列组合了,毕竟高考必考的嘛.我们先来回忆下这两个的公式是啥: 排列组合公式 如果看到这个还有一丢丢的印象,说明大家的基础都还不错.那么问题来了,大家都 ...

  4. 算法笔记 --- 排列组合

    排列组合的计算公式 转载于:https://www.cnblogs.com/zhongzhiqiang/p/5809116.html

  5. C++经典算法题-排列组合

    27.Algorithm Gossip: 排列组合 说明 将一组数字.字母或符号进行排列,以得到不同的组合顺序,例如1 2 3这三个数的排列组合有: 1 2 3.1 3 2.2 1 3.2 3 1.3 ...

  6. 数学和算法之---排列组合

    本文大部分内容摘自网络只是本人稍加整理分享,供大家学习交流. 排列的概念 从n个不同的元素中,任取m(m<=n)个元素按照一定的顺寻排成一列,叫做从n个不同元素中取出m个元素的一个排列.从n个不 ...

  7. 必知C++算法之排列组合基本操作

    概率组合题目分类 1.高中数学为基础的古典概率计算方法 2.斐波那契数列和卡特兰数 6x9的方格,从左上角到右下角,每次只能向下或向右,一共多少种不同走法 一共13步,五步向下,剩下8步向右 组合问题 ...

  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, ...

  9. 算法 64式 17、排列组合算法整理

    1算法思想 排列组合 1.1含义 排列: 含义:从元素列表中取出指定个数的元素进行排序 公式:从n个不同元素中取出m个元素的排列个数=n!/(n-m)! 组合: 含义:从元素列表中取出指定个数的元素, ...

最新文章

  1. Jumony入门(二)初识选择器
  2. TrojanDownloader简单分析
  3. AngularJS(6)-选择框Select
  4. 也说春运网络购票:12306的码农没有你想的那么弱 [转]
  5. EXE.DLL文件图标导出器[免费下载]
  6. idea中artifacts、facets、modules是什么意思?
  7. python文本文档_Python3 File
  8. oracle数据库激活控制文件位置,Oracle数据库之Oracle 重建控制文件一例
  9. c语言sqart函数格式,2019-07-29 复习C语言入门知识
  10. Kafka 启动报错 AccessDeniedException
  11. idea 自动同步文件本地内容设置
  12. IRT模型估计-EM算法
  13. 【软件测试面试】测试开发一面面试题+回答,大伙感受下强度咋样......
  14. css小鸡破壳,小鸡出壳是小鸡自己破壳,还是鸡妈妈帮助破壳?
  15. 【原创】Syncthing搭建自己的中继服务和发现服务
  16. echart 报表统计
  17. 百度地图调用加载显示Marker,并添加点击事件
  18. javaweb JSP JAVA旅游网站在线旅游信息网站(旅游系统旅游网站)jsp旅游管理系统
  19. 每日一句:day01——From Zero To Hero
  20. labview csv文件处理_LabVIEW程序写完后,你知道怎样保护你的源代码隐私吗?

热门文章

  1. Qt tabwidget 标签页设置tabbar标题,tabwidget设置透明色
  2. C++ 随记三 (一些杂项)
  3. 小学生C++编程基础 课程8(B)
  4. turtle 里都write() 可以选择的字体有哪些
  5. python语言input和if else的嵌套使用_Python中if语句嵌套的方法
  6. 长期戴耳机的危害有多大?有没有不伤耳朵的蓝牙耳机?
  7. JQuery在线截取图片
  8. JavaSE进阶 | import、访问控制权限、Object、匿名内部类
  9. 老赖的未来生活,竟然是这样!
  10. 帆软 - ²平方号,€欧元符号 显示乱码