回溯方法的学习和总结
1. 按照博主的划分,回溯问题分为:子集型、组合型、排列型。
2. 子集型的考虑方法分成:从过程分析,选或不选;从答案角度分析,选择哪个。如果有重复的元素,应该如何处理
3. 需要总结剪枝技巧,
2.1 排列型问题
这是计算排列个数的问题,从n个数中选n个数的排列个数,符号表示Ann,1-2-3 和 1-3-2 是不同的排列,n个数的排列个数是n的阶乘。
46. 全排列 从没有重复数字的序列nums[] 中选择数字,查看所有的排列个数。在选取过程中,使用b_flag[] 进行标记,只能选未选取的。
47. 全排列 II 从有重复数字的序列nums[] 中选择数字,查看所有的排列个数。在选取过程中,除了使用b_flag[]进行标记, 还使用如下判断条件:
if (p_flag[ix] || (ix > 0 && !p_flag[ix - 1] && nums[ix] == nums[ix - 1] )) continue;
if (p_flag[ix] || (ix > 0 && !p_flag[ix - 1] && nums[ix] == nums[ix - 1] ))
上述语句中的!p_flag[ix-1] 写成p_flag[ix-1] 也可以得到正确答案,但是效率会下降。因为前者是同层剪枝,对于[1,1,1]只选取一次,就可以得到结果,其他情况直接被剪枝。而后者是不同层剪枝,在尝试所有的排列都失败后,最后一次才获取到正确结果。
2.2 子集型问题
2.3 组合型问题
目前, 分析这种问题,我认为“选哪个”的方法,更好理解。边界条件和剪枝条件更好确认