参考图的深度优先遍历:先用 n 个数字构建出 n * n 大小的矩阵,然后通过矩阵进行深度遍历
通过判断子集中是否包含某一元素,来判断一个元素是否isVisited
public class Solution {
public static void main(String[] args) {
int[] nums = new int[]{1, 2, 3};
System.out.println(permuteUnique(nums));
}
public static List<List<Integer>> permuteUnique(int[] nums) {
int n = nums.length;
int[][] matrix = new int[n][n];
for (int i = 0; i < matrix.length; i++) {
for (int j = i + 1; j < matrix.length; j++) {
matrix[i][j] = 1;
matrix[j][i] = 1;
}
}
List<List<Integer>> res = new ArrayList<>();
for (int i = 0; i < matrix.length; i++) {
ArrayList<Integer> subRes = new ArrayList<>();
dfs(matrix, nums, i, subRes, res);
}
return res;
}
//图矩阵的层次遍历
public static void dfs(int[][] matrix, int[] nums, int index,
ArrayList<Integer> subRes, List<List<Integer>> res) {
subRes.add(nums[index]);
int vertexIndex = getFirstNeighbor(matrix, index);
while (vertexIndex != -1) {
System.out.println(vertexIndex);
if (!subRes.contains(nums[vertexIndex])) {
dfs(matrix, nums, vertexIndex, subRes, res);
int lastIndex = subRes.size() - 1;
subRes.remove(lastIndex);
}
vertexIndex = getNextNeighbor(matrix, index, vertexIndex);
}
if (subRes.size() == matrix.length) {
ArrayList<Integer> temp = new ArrayList<>();
for (Integer item : subRes) {
temp.add(item);
}
res.add(temp);
}
}
//得到第一个邻接结点的下标 vertexIndex
public static int getFirstNeighbor(int[][] matrix, int index) {
for (int i = 0; i < matrix.length; i++) {
if (matrix[index][i] > 0)
return i;
}
return -1;
}
//根据前一个邻接结点的下标来获取下一个邻接结点
public static int getNextNeighbor(int[][] matrix, int index, int firstNeighbor) {
for (int i = firstNeighbor + 1; i < matrix.length; i++) {
if (matrix[index][i] > 0)
return i;
}
return -1;
}
}