LeetCode: Permutation I & II

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].

思路有两个,一个是dfs,一个是递归。

dfs的关键是,有一个visited数组来标记哪些元素访问过。这个非常重要,因为我第一次面试就卡在了这个上。。。

LeetCode: Permutation I & II
 1 public class Solution {
 2     public static ArrayList<ArrayList<Integer>> permute(int[] num) {
 3         boolean[] visited = new boolean[num.length];
 4         ArrayList<Integer> tmp = new ArrayList<Integer>();
 5         ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
 6         permute2(num, visited, tmp, result);
 7         return result;
 8     }
 9     
10     public static void permute2(int[] num, boolean[] visited, ArrayList<Integer> tmp, ArrayList<ArrayList<Integer>> result) {
11         if (tmp.size() == num.length) {
12             result.add(new ArrayList<Integer>(tmp));
13             return;
14         }
15         for (int i=0; i<num.length; i++) {
16             if (visited[i] == false) {
17                 tmp.add(num[i]);
18                 visited[i] = true;
19                 permute2(num, visited, tmp, result);
20                 visited[i] = false;
21                 tmp.remove(tmp.size()-1);
22             }
23         }
24     }
25 }
LeetCode: Permutation I & II

递归很好想,就是先产生[1,2],[2,1].然后在把3放到对应的位置上。

LeetCode: Permutation I & II
 1 public class Solution {
 2     public ArrayList<ArrayList<Integer>> permute(int[] num) {
 3         ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
 4         if (num == null || num.length == 0) return null;
 5         else if (num.length == 1) {
 6             ArrayList<Integer> cell = new ArrayList<Integer>();
 7             cell.add(num[0]);
 8             result.add(cell);
 9         }
10         else {
11             int[] l = new int[num.length-1];
12             int t = num[num.length-1];
13             for (int i = 0; i<l.length; i++) l[i] = num[i];
14             ArrayList<ArrayList<Integer>> current = permute(l);
15             for (ArrayList<Integer> c : current) {
16                 int size = c.size();
17                 for (int j = 0; j<=size; j++) {
18                     ArrayList<Integer> w = new ArrayList<Integer>();
19                     w.addAll(c);
20                     w.add(j, t);
21                     result.add(w);
22                 }
23             }
24         }
25         return result;
26     }
27 }
LeetCode: Permutation I & II

 


Given a collection of numbers that might contain duplicates, return all possible unique permutations.

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

有重复数字的话,用递归就不是很好做。每一次产生一个结果就要判断这个结果是否已经包含在result中,所以时间长。

用dfs做的话用两个地方需要注意。

一个是要对字符串进行排序。因为如果排序的话,可以很好避免因为重复数字产生的重复的情况。

第二个就是如何避免因为重复数字产生的重复情况。因为已经排好序,所以每次选择下一个数字的时候只要避免和之前的数字重复就行。

比如[1,2,3,3,4].当我们产生[1,2,3]的时候,我们只要避免回溯的时候再次选择3,从而产生[1,2,3]就行了。

LeetCode: Permutation I & II
 1 public class Solution {
 2     public ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
 3         Arrays.sort(num);
 4         boolean[] visited = new boolean[num.length];
 5         ArrayList<Integer> tmp = new ArrayList<Integer>();
 6         ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
 7         permute2(num, visited, tmp, result);
 8         return result;
 9     }
10     
11     public static void permute2(int[] num, boolean[] visited, ArrayList<Integer> tmp, ArrayList<ArrayList<Integer>> result) {
12         if (tmp.size() == num.length) {
13             result.add(new ArrayList<Integer>(tmp));
14             return;
15         }
16         for (int i=0; i<num.length; i++) {
17             if (visited[i] == false) {
18                 tmp.add(num[i]);
19                 visited[i] = true;
20                 permute2(num, visited, tmp, result);
21                 visited[i] = false;
22                 tmp.remove(tmp.size()-1);
23                 while (i<num.length-1 && num[i] == num[i+1]) i++;
24             }
25         }
26     }
27 }
LeetCode: Permutation I & II

LeetCode: Permutation I & II

上一篇:[原创]传递UIScrollView的滑动事件到其子视图中


下一篇:[Leetcode]-- Subsets