带重复元素的排列
题目
给出一个具有重复数字的列表,找出列表所有不同的排列。
样例
给出列表 [1,2,2],不同的排列有:
挑战
使用递归和非递归分别完成该题。
题解
1.递归解法
在无重复元素的全排列算法的基础上加入重复数字判断就可以了,即[start,j-1]之间是否有和nums[j]相同的数。
class Solution {
/**
* @param nums: A list of integers.
* @return: A list of unique permutations.
*/
private ArrayList<List<Integer>> list = new ArrayList<List<Integer>>();
public List<List<Integer>> permuteUnique(int[] nums) {
permutation(nums,0,nums.length);
return list;
}
private void permutation(int[] nums, int start, int end)
{
if (start == end)
{
ArrayList<Integer> arrList = new ArrayList<Integer>();
for (int i=0;i<end;i++)
{
arrList.add(nums[i]);
}
list.add(arrList);
}
else
{
for (int j=start;j<end;j++)
{
if (isValid(nums,start,j))
{
swap(nums,j,start);
permutation(nums,start+1,end);
swap(nums,j,start);
}
}
}
}
private void swap(int[] nums, int i, int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private boolean isValid(int[] nums,int start,int index)
{
for (int i=start;i<index;i++)
{
if (nums[i] == nums[index])
{
return false;
}
}
return true;
}
}
2.字典法
字典法天然可以处理重复元素问题。
class Solution {
/**
* @param nums: A list of integers.
* @return: A list of unique permutations.
*/
public List<List<Integer>> permuteUnique(int[] nums) {
ArrayList<List<Integer>> result = new ArrayList<List<Integer>>();
if (nums.length == 0)
{
result.add(new ArrayList<Integer>());
return result;
}
Arrays.sort(nums);
addList(result,nums);
while (nextPermutation(nums))
{
addList(result,nums);
}
return result;
}
private void addList(ArrayList<List<Integer>> list, int[] nums)
{
ArrayList<Integer> arrList = new ArrayList<Integer>();
for (int i=0;i<nums.length;i++)
{
arrList.add(nums[i]);
}
list.add(arrList);
}
private boolean nextPermutation(int[] arr)
{
int i=arr.length-2;
boolean bFind = false;
for(;i >= 0;i--)
{
if(arr[i] < arr[i + 1])
{
bFind = true;
break;
}
}
if (!bFind)
{
return false;
}
int j = i;
for (int k=i+1;k<arr.length;k++)
{
if (arr[k] > arr[i])
{
j = k;
}
}
swap(arr, i, j);
reverse(arr, i+1, arr.length-1);
return true;
}
private void reverse(int[] arr,int start, int end)
{
while (start < end)
{
swap(arr, start++, end--);
}
}
private void swap(int[] nums, int i, int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
Last Update 2016.9.28