Leetcode: Permutations

Given a collection of numbers, return all possible permutations.

For example,
[1,2,3] have the following permutations:
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].

Analysis: 这道题跟N-QueensSudoku SolverCombination SumCombinations, Subsets, Generate Parentheses等一样,也是一个NP问题

又是把所有满足条件的结果存到一个ArrayList里面, 之前也有类似的如Letter combination of a Phone Number这道题。这种类型的题其实形成了一个套路,套路就是,recursion参数包括最终结果的集合(ArrayList),input(String),递归层次level(int),某一条具体的路径Path,当前外部环境

一般来说是:ArrayList<ArrayList<>>, ArrayList<>, input, 当前外部环境(可以是sum remain, 可以如本例是visited过的数组元素),递归层次level(int)

第二遍的做法:

public class Solution {
    public ArrayList<ArrayList<Integer>> permute(int[] num) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> element = new ArrayList<Integer>();
        boolean[] visited = new boolean[num.length];
        helper(num, result, element, visited);
        return result;
    }
    
    public void helper(int[] num, ArrayList<ArrayList<Integer>> result, ArrayList<Integer> element, boolean[] visited){
        if (element.size() == num.length){
            // duplicate element and add it to result (element would be changed from time to time. If directly use element
            // only result would be changed when element changed)
            result.add(new ArrayList<Integer>(element)); 
            return;
        }
        
        for(int i=0; i<num.length; i++){
            if(!visited[i]){
                visited[i] = true;
                element.add(num[i]);
                helper(num, result, element, visited);
                
                // After providing a complete permutation, pull out the last number, 
                element.remove(element.size()-1);
                visited[i] = false;
            }
        }
    }
}

 Li Shi的 iterative 做法(还未深究)

 1 public class Solution {
 2     public List<List<Integer>> permute(int[] num) {
 3         int len = num.length;
 4         List<List<Integer>> resSet = new ArrayList<List<Integer>>();
 5         List<Integer> curSeq = new ArrayList<Integer>();
 6         boolean[] used = new boolean[len];
 7         Arrays.fill(used,false);
 8         Arrays.sort(num);
 9         int curIndex = 0;
10         curSeq.add(-1);
11         while (curIndex!=-1){
12             if (curIndex==len){
13                 List<Integer> temp = new ArrayList<Integer>();
14                 for (int i=0;i<curSeq.size();i++) temp.add(num[curSeq.get(i)]);
15                 resSet.add(temp);
16                 curIndex--;
17                 continue;
18             }
19             
20             int val = -1;
21             if (curSeq.size()>curIndex){
22                 val = curSeq.get(curIndex);
23                 if (val!=-1)
24                     used[val]=false;
25                 curSeq.remove(curIndex);
26             }
27 
28             boolean find = false;
29             for (int i=val+1;i<len;i++)
30                 if (!used[i]){
31                     used[i]=true;
32                     curSeq.add(i);
33                     curIndex++;
34                     find = true;
35                     break;
36                 }
37             
38             if (find)
39                 continue;
40             else 
41                 curIndex--;
42         }
43 
44         return resSet;
45     }
46 }
原文地址:https://www.cnblogs.com/EdwardLiu/p/3811782.html