题目描述:给定一个数组,输出它的全排列,数组中可能存在相同的数
解题思路:一开始的想法是先输出全排列,然后去掉其中的重复项,全排列的输出根据将一个数插在前面所有数形成的所有排列的不同位置上得到,发现有重复项,因此应该对排列排序后再加入新的数。但是这种方法耗费时间太长。看了tags之后发现使用回溯的方法进行剪枝,那就是在形成新的排列的时候查看列表中是否已存在此项,已存在就不再加入,这样就不需要最后的distinct操作了
C#知识点:IqualityComparer,IComparer接口的运用
public class Solution {
public IList<IList<int>> PermuteUnique(int[] nums) {
List<IList<int>> permutes = new List<IList<int>>();
if (nums.Length == 0)
return permutes;
//int product=1;
//for (int i = nums.Length; i >= 1; i--)
// product *= i;
//for (int i = 0; i < product; i++)
//permutes.Add(new List<int>());
permutes.Add(new List<int>() { nums[0] });
//List<IList<int>> ss = new List<IList<int>>();
for (int i = 1; i < nums.Length; i++)
{
permutes=Permute(nums[i], permutes);
//permutes.Sort(new Comparint());
}
//var ss=permutes.Distinct(new Comparint());
return permutes.ToList<IList<int>>();
}
private List<IList<int>> Permute(int x, List<IList<int>> permutes)
{
int length = permutes[0].Count;
int i = 0;
List<IList<int>> ss = new List<IList<int>>();
while (i < permutes.Count)
{
int[] array = new int[length];
permutes[i].CopyTo(array, 0);
for (int j = 0; j <= length; j++)
{
List<int> item = array.ToList<int>();
item.Insert(j, x);
if (!ss.Contains(item,new Comparint()))
ss.Add(item);
}
i++;
}
return ss;
}
class Comparint : IEqualityComparer<IList<int>>
{
public bool Equals(IList<int> x1, IList<int> x2)
{
if (x1.Count != x2.Count)
return false;
bool b = true;
for (int i = 0; i < x1.Count; i++)
{
if (x1[i] != x2[i])
{
b = false;
break;
}
}
return b;
}
public int GetHashCode(IList<int> obj)
{
return obj.ToString().GetHashCode();
}
}
}