题目:
解题:



运算结果:

解题过程:
一、读题:
题目说全排列,1,2,3 输出 6 组。
就是把里面所有数字拿出来,换顺序,每个数字只能用一次,所有不同顺序都要收集起来。
二、框架
1、把所有顺序不漏,不重复的找出来
直接写6个if?不行!数组长度变了,答案数量就变了。需要一种"挨个选数字"的方式,自动去尝试所有组合。
2、选过的数字不能再次选择第二次
开一个标记数组used,和nums一样长。used【i】=ture代表nums【i】已经选进当前列表了,不能再选。
3、我现在选了一部分数字,比如已经选了 1,2,后面要接着选;如果这条路走到头了(选满 3 个),我要记下这个答案,然后退回去,换别的数字试。
比如 1,2,3 找到之后,我要退回去,把 3 拿掉,看看还有没有别的数字能放第三位;没有就继续退,把 2 拿掉,第三位换成 3,变成 1,3,2。
这个 "选数字 → 往下继续选 → 走不通了退回、擦掉刚才选的,换别的" 思想,就是回溯。
三、总的说,维护一个当前正在拼的数组 path,维护 used \[\] 标记哪些下标用过
每次循环遍历所有数字:没被用过就选它,放进 path,标记 used
如果 path 长度等于 nums 长度:这是一组合法排列,存进答案
存完或者这条路试完了:把刚才选的数字删掉,used 取消标记(退回现场,换别的分支)
四、思考递归的终止条件。
path 是我正在拼的排列。nums 一共 3 个数。
当 path 里面数字数量 == nums 里面数字数量 → 说明全部选完了,这是一个完整排列。
比如 path=1,2,3,长度 = 3,满足条件,复制一份存到结果 res 里。(为什么要复制一份,path 是一直在修改的数组,后面我要删掉数字回溯。如果直接把 path 放进 res,后面一改,res 里面存的内容也跟着变了,就错了。)
五、怎么循环,怎么选数字
我现在假设当前 path=1,used=T,F,F
我要选第二个位置的数字:
我得从头到尾扫一遍 nums 里每一个下标 i:
i=0:used 0=true,已经选了,跳过,不能再拿 1;
i=1:used 1=false,可以拿 2;
i=2:used 2=false,可以拿 3。