题目为
给定一个可包含重复数字的序列,返回所有不重复的全排列。
思路为,相比较与全排序题目,增加了数组包含重复数。思路为键值对判断重复。代码如下
public IList<IList<int>> PermuteUnique(int[] nums)
{
List<int> temp = new List<int>();
IList<IList<int>> res = new List<IList<int>>();
PermuteUniqueDetail(nums, temp, res);
return res;
}
//判断该位置是否已经存储 键存储元素在数组中位置
Dictionary<int, int> dic = new Dictionary<int, int>();
//重复判断
Dictionary<string, int> dicRes = new Dictionary<string, int>();
public void PermuteUniqueDetail(int[] nums, List<int> temp, IList<IList<int>> res)
{
if (temp.Count() == nums.Length && !dicRes.ContainsKey(string.Join(",", temp.ToArray())))
{
res.Add(new List<int>(temp));
dicRes.Add(string.Join(",", temp.ToArray()), 1);
return;
}
for (int i = 0; i < nums.Count(); i++)
{
if (dic.ContainsKey(i))
{
continue;
}
dic.Add(i, 0);
temp.Add(nums[i]);
PermuteUniqueDetail(nums, temp, res);
temp.RemoveAt(temp.Count - 1);
dic.Remove(i);
}
}
看了题解,参考精选题解,精选题解链接给出了排序加减枝的算法。
代码如下
public IList<IList<int>> PermuteUnique(int[] nums)
{
List<int> temp = new List<int>();
IList<IList<int>> res = new List<IList<int>>();
int[] newNums= nums.OrderBy(e => e).ToArray(); ;
PermuteUniqueDetail(newNums, temp, res);
return res;
}
//判断该位置是否已经存储 键存储元素在数组中位置
Dictionary<int, int> dic = new Dictionary<int, int>();
public void PermuteUniqueDetail(int[] nums,List<int> temp, IList<IList<int>> res)
{
if (temp.Count()==nums.Length)
{
res.Add(new List<int>(temp));
return;
}
for (int i = 0; i < nums.Length; i++)
{
if (dic.ContainsKey(i))
{
continue;
}
if (i > 0 && nums[i] == nums[i - 1] && dic.ContainsKey(i - 1))
{
continue;
}
dic.Add(i, 0);
temp.Add(nums[i]);
PermuteUniqueDetail(nums, temp, res);
temp.RemoveAt(temp.Count()-1);
dic.Remove(i);
}
}