赞
踩
1,递归调用之后,即递归方法的下一行,一定要进行回溯一级!
2,递归触底之后,也是一定要回溯一级!
·
给你一个数字n,请你生成并返回所有 从 1 到 n 可能的全排列 。你可以 按任意顺序 返回答案。
比如:
输入:n = 3 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
·
把从1~n的每个数字,抽象成一个以该元素为根节点的多叉树,
以n为4举例,如图:
这是以1为根节点的多叉树:
还有以2、3、4为根节点的多叉树;
DFS该多叉树,记录路径;
比如说,以1为起点:
注意:上述每一次递归调用之后,即递归方法的下一行,一定要进行回溯一级!
递归触底了,当然也是要回溯一级。
·
- //全排列
- public static List<List<Integer>> permute(int n) {
-
- Set<Integer> alreadyAddedSet=new HashSet<>(); //利用HashSet,存储遍历过的元素,防止重复
- Deque<Integer> deque = new LinkedList<>(); //辅助栈,记录递归的路径
-
- //递归方法:
- helper(alreadyAddedSet, n, deque);
-
- System.out.println("nodeValList = " + nodeValList);
-
- return nodeValList;
- }
-
-
- private static List<List<Integer>> nodeValList = new ArrayList<>(); //全排列结果,存储所有的路径;
-
- /**
- * 全排列:
- * @param deque 辅助栈,记录递归的路径;
- * @param hashSet 利用HashSet,存储存储过的元素,防止重复
- */
- public static void helper(Set<Integer> alreadyAddedSet,int n, Deque<Integer> deque) {
- for (int currEle = 1; currEle <= n; currEle++) {
- //避开已经存储过的元素
- if (alreadyAddedSet.contains(currEle)) {
- continue;
- }else {
- //将当前的元素加入路径:
- alreadyAddedSet.add(currEle);
- deque.push(currEle);
-
- if (deque.size() < n) {
- //递归:
- helper(alreadyAddedSet,n, deque);
-
- //递归之后的下一行,切记要回溯一级:
- //路径回退一级:
- //因为使用了Set作为防止元素重复遍历,所以Set也要回退一下,退出刚才的元素:
- alreadyAddedSet.remove(deque.pop());
-
- }
- //当栈的元素数量==n了, 说明触底了
- else{
- // 记录这一条路径:
- nodeValList.add(new LinkedList<>(deque));
- //触底了,要回溯一级:
- //路径回退一级:
- //因为使用了Set作为防止元素重复遍历,所以Set也要回退一下,退出刚才的元素:
- alreadyAddedSet.remove(deque.pop());
- return ;
- }
-
- }
- }
- return ;
- }
·
输入:3
输入:4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。