LeetCode - 46. 全排列

132 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。


原题:46. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。(可以 按任意顺序返回答案。)

解题思路:

因为题目要求全排列,也就是每一个结果中包含给定数组的每一个元素,其实就是一个排列组合的题目。可以通过回溯的方法解决。

递归方法需要传递的参数有:

  • nums 给定的数组
  • result 结果集
  • seq 用来生成每一个合法的排列

除了以上三个外,还需要一个重要的参数,用来记录每一个元素是否已经在结果中使用过,因为给定数组中的每个元素只能使用一次。可以定义一个与给定数组长度相同的布尔类型数组 visited,数组中的所有元素初始值都是 false,每当使用过一个元素之后,visited 中与使用过的元素下标相同的元素值变成 true

回溯方法的定义如下:

private static void backtrace(int[] nums, List<List<nteger>> result, int curr, int[] visited, ArrayList<Integer> seq)

递归结束的条件就是结果列表 seq 的长度与给定数组的长度相同,达到结束条件后,将 seq 中的结果添加到 result 中即可。

每层调用会便利给定数组中的所有元素,通过与 visited 中相同索引的值判断是否已经使用过,没有使用过的话就加入 seq 中,在进行下一层递归调用,之后再恢复状态。

最终代码:

class Solution {
    public static List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        if(nums.length < 1){
            return res;
        }
        int[] visited = new int[nums.length];
        backtrace(nums, result, visited, new ArrayList<Integer>());
        return result;
    }

    private static void backtrace(int[] nums, List<List<nteger>> result, int curr, int[] visited, ArrayList<Integer> seq) {
        if(seq.size() == nums.length){
            result.add(new ArrayList<>(seq));
            return;
        }
        for(int i = 0; i <nums.length; i++){
            if(visited[i] == 1){
                continue;
            }
            seq.add(nums[i]);
            visited[i] = 1;
            backtrace(nums, result, visited, seq);
            seq.remove(temp.size()-1);
            visited[i] = 0;
        }
    }
}