今天是2020年4月25日,星期六。
题目描述
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
题目分析
全排列问题是一个很经典、很基础的“回溯”算法的问题。对于“回溯”算法的介绍大家可以参考weiwei大佬的题解「从全排列问题开始理解「回溯」算法(深度优先遍历 + 状态重置 + 剪枝)」和官方题解「全排列」中weiwei大佬的视频讲解。
本题目中使用深度优先遍历,将全排列问题转化为一个树的深度优先遍历,并使用“回溯”的方法回到上一层节点,继续状态的转移。这里还需要大家仔细去体会、学习和练习,小编就不在这里赘述了。
参考代码
class Solution {
public List<List<Integer>> permute(int[] nums) {
int length = nums.length;
// 保存所有可能全排列
List<List<Integer>> result = new ArrayList<>();
if (length == 0) {
return result;
}
boolean[] used = new boolean[length];
List<Integer> path = new ArrayList<>();
dfs(nums, length, 0, path, used, result);
return result;
}
/**
* 按树形结构来遍历
*
* @param nums
* @param length
* @param depth 当前遍历到的属性的层次数
* @param path
* @param used
* @param result
*/
private void dfs(int[] nums, int length, int depth, List<Integer> path, boolean[] used, List<List<Integer>> result) {
if (depth == length) {
result.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < length; i++) {
if (!used[i]) {
path.add(nums[i]);
used[i] = true;
dfs(nums, length, depth + 1, path, used, result);
// 注意这里是回溯过程,从深层次节点到浅层次节点的过程,代码是和递归形式是对称的。
used[i] = false;
path.remove(path.size() - 1);
}
}
}
}