java解决全排列问题
全排列问题1
给定一个可包含重复数字的序列 nums ,按任意顺序返回所有不重复的全排列。
- 思路
我们把问题看成n个排列成一行的空格,从左往右依次填入给定的n个数,每个数只能使用一次,可以使用回溯法。
递归函数backtrack(idx, perm)表示当前排列为perm,下一个待填入的位置是第idx个位置,下标从0开始。(1)如果idx == n,说明填完了n个位置,找到了一个可行解,把perm放入结果数组中,递归结束;
(2)如果idx < n,需要考虑第idx个位置填那个数。使用标记数组visited来标记已经填过的元素,那么在填第idx个数的时候遍历给定的n个数,如果这个数没有被标记过,尝试填入,并将其标记,继续尝试下一个位置,调用backtrack(idx+1, perm)。搜索回溯时要撤销该位置填的数以及标记,并尝试其他没被标记过的数。
(3)要解决重复问题,保证填第idx个数的时候重复数字只会被填入一次。我们选择对原数组排序,保证相同的数字都相邻,然后每次填入的数一定是这个数所在重复数集合中从左往右第一个未被填过的数字。
- 示例
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class Demo {public static void main(String[] args) {int[] nums = {1, 1, 2};Solution solution = new Solution();List<List<Integer>> lists = solution.permuteUnique(nums);System.out.println(lists);}
}class Solution {boolean[] visited;public List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> result = new ArrayList<>();visited = new boolean[nums.length];Arrays.sort(nums);List<Integer> perm = new ArrayList<>();backtrack(nums, result, 0, perm);return result;}private void backtrack(int[] nums, List<List<Integer>> result, int idx, List<Integer> perm) {if (idx == nums.length) {result.add(new ArrayList<>(perm));return;}for (int i=0;i<nums.length;i++) {if (visited[i] || (i > 0 && nums[i] == nums[i-1] && !visited[i-1]))continue;perm.add(nums[i]);visited[i] = true;backtrack(nums, result, idx + 1, perm);visited[i] = false;perm.remove(idx);}}
}
[[1, 1, 2], [1, 2, 1], [2, 1, 1]]
全排列问题2
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以按任意顺序返回答案。
class Solution {boolean[] visited;public List<List<Integer>> permute(int[] nums) {List<List<Integer>> res = new ArrayList<>();visited = new boolean[nums.length];List<Integer> perm = new ArrayList<>();backtrace(res, nums, 0, perm);return res;}private void backtrace(List<List<Integer>> res, int[] nums, int idx, List<Integer> perm) {if (idx == nums.length) {res.add(new ArrayList<>(perm));return;}for (int i=0;i<nums.length;i++) {if (visited[i]) {continue;}perm.add(nums[i]);visited[i] = true;backtrace(res, nums, idx+1, perm);visited[i] = false;perm.remove(idx);}}
}