问题描述:
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]
, and [3,2,1]
.
原问题链接:https://leetcode.com/problems/permutations/
问题分析
这个问题可以归结为典型的排列问题。在之前的一篇文章里有过详细的讨论。 在前面的文章里,我们提到的字典序排列的方法就可以很好的解决这个问题。在每次生成字典序的排列最后我们将这个序列加入到List里面,这样就可以得到所有的排列生成列表。
而字典序排列的过程概括起来就是如下这么个步骤:
- 找最后面的连续递增点。
- 根据找到的点后面找最接近的大于它的元素。
- 倒置后面序列里的元素。
详细实现见如下代码:
public class Solution { public List<List<Integer>> permute(int[] num) { Arrays.sort(num); List<List<Integer>> lists = new ArrayList<List<Integer>>(); lists.add(appendList(num)); while(true) { int start = findStart(num); if(start == -1) break; int end = findEnd(num, start); if(end == -1) break; swap(num, start, end); reverse(num, start + 1, num.length - 1); lists.add(appendList(num)); } return lists; } private List<Integer> appendList(int[] num) { List<Integer> list = new ArrayList<Integer>(); for(int i = 0; i < num.length; i++) list.add(num[i]); return list; } private int findStart(int[] num) { for(int i = num.length - 2; i >= 0; i--) if(num[i] < num[i + 1]) return i; return -1; } private int findEnd(int[] num, int l) { for(int i = num.length - 1; i > l; i--) if(num[i] > num[l]) return i; return -1; } private void reverse(int[] num, int l, int r) { while(l < r) { swap(num, l, r); l++; r--; } } private void swap(int[] num, int i, int j) { int temp = num[i]; num[i] = num[j]; num[j] = temp; } }