notice:
if ( curList.contains(arr[i]) ){
continue;
}
记忆点:
看解释图中的三层树:
每一层,是for实现的,可以看到是从头扫到尾,已经有了就不要了
层与层之间,是靠recursion传递current path,一个数一个数加的
notice:每一次跳出时,要删去最后一个元素
https://leetcode.com/problems/permutations/
Given a collection of distinct 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],
[3,2,1]
]
input: given an array
output: it's to return all the permutations of this array
corner: when the array is null or its length is zero
Based on the question, we can build a solution tree, where at the root, we have n = arr.length
choices, then the second level we have n - 1
choices, then continue with decreasing one at each level.
Then we can use DFS algorithm to traverse the solution tree.
We need a list of list
to store the final permutations, and a current list
to track the current path.
例如,[1,2,3]这个例子,
可以画出如左边树状组成的解空间。
具体需要current list来储存每一条path,
当path内部元素达到和给定array一样长时,就可以把它加入到res中。
跑个test case就是,从index=0开始遍历,
current list可以先装入1,
然后进入下一层,先check了现在path里面已经有了1,所以加入2,
再一次进入下一层,check之后,这时能加的只有3了,
此时长度=array的length,可以加入到res,并且返回。
返回后,current list需要remove掉最后一位,因为要为下一个情况让座。
这样就可以写出recursion的函数:
base case就是当长度等于array.length时返回。
current level要做的就是从0扫到length-1,
先check当前path中是否包含此元素,包含则跳过,否则加入到path,
加完一个之后,进入next level加入下一个元素,
直到每一个path都完成后返回,
返回后要remove掉最后一个位置。
Before we add a new number into the path, firstly is to check whether it's already in the list, if yes, we ignore this number, and move to next one, if no, add it.
For each single path, we will go through root to leaf node. When the path has finished iterating all the numbers and return to the upper level, it will first delete the last number in the path, so that the curList
can add new nodes.
Time: O(n! * n) ( n!: solutions #, n: from curList.contains(arr[i])
)
Space: O(n) ( n: curList
without considering result and recursion stack )
public class Solution{
public List<List<Integer>> permutations(int[] arr){
List<List<Integer>> res = new ArrayList<List<Integer>>();
//corner
if ( arr == null || arr.length == 0 ){
return res;
}
//core
List<Integer> curList = new ArrayList<>();
helper(res, curList, arr);
return res;
}
public void helper(List<List<Integer>> res, List<Integer> curList, int[] arr){
//base
if ( curList.size() == arr.length ){
res.add(new ArrayList<Integer>(curList));
return ;
}
//current
for ( int i = 0; i < arr.length; i++ ){
if ( curList.contains(arr[i]) ){
continue;
}
curList.add(arr[i]);
//next
helper(res, curList, arr);
curList.remove(curList.size() - 1);
}
}
}