文章目录
题目思路代码结语参考资料
题目
46. 全排列
思路
这里我主要讲的是回溯法的做法。
回溯主要是基于递归的思想,一定要记得,在递归结束后,要撤销选择。在递归之前做出选择,在递归之后撤销刚才的选择,就能正确得到每个节点的选择列表和路径。
大体框架如下:
def backtrack(选择列表,路径
):
if 满足结束条件
:
操作res
return
for 选择
in 选择列表
:
if 选择不合法
continue
选择列表
.remove
(选择
)
路径
.add
(选择
)
backtrack
(选择列表,路径
)
路径
.remove
(选择
)
借用labuladong公众号的一张图来帮助理解一下,这道题的过程大概如下。
代码
import java
.util
.*
;
public class Solution {
List
<List
<Integer>> res
= new LinkedList<>();
public List
<List
<Integer>> permute(int[] nums
) {
if (nums
.length
== 0) {
return res
;
}
LinkedList
<Integer> track
= new LinkedList<>();
backtrack(nums
, track
);
return res
;
}
void backtrack(int[] nums
, LinkedList
<Integer> track
) {
if (track
.size() == nums
.length
) {
res
.add(new LinkedList(track
));
return;
}
for(int i
=0; i
< nums
.length
; i
++){
if(track
.contains(nums
[i
])){
continue;
}
track
.add(nums
[i
]);
backtrack(nums
, track
);
track
.removeLast();
}
}
}
结语
当然就这道题而言,还有很多更优秀的解法,比如dfs、bfs搭配visited等方法剪枝,这些我以后会争取多做些笔记。
比较适用回溯算法的题还有这些,冲冲冲。
39.组合总和
40. 组合总和 II
46. 全排列
47. 全排列 II
78. 子集
90. 子集 II
51. N皇后
参考资料
我的leetcode刷题历程是跟着labuladong大佬混的,没错,就是那个leetcode上一出题解,必属精品的那位。