回溯算法,加个去重,去重用完要归零(不是真的零,归成一个数组没有的数就行)
回退的最后一次记录下来,再进入循环时,和数组进行比对
public class Solution {//写一个回溯,不过好像这样不包含重复的,如果是交换法的话,检测下交换的二者是否相同就行了
List<IList<int>> res = new List<IList<int>>();
int repeat=256;
public IList<IList<int>> PermuteUnique(int[] nums) {
int len =nums.Length;
bool[] used = new bool[len];
Array.Sort(nums); //先把数排下序,我也不太清楚,为啥不排序就乱了...
bt(nums,used,new Stack<int>(),len);
return res;
}
void bt(int[] nums,bool[] used,Stack<int> path,int len)
{
if(path.Count==len)//
{
int[] arr = new int[]{};
arr = path.ToArray();
res.Add(arr);
return;
}
for(int i=0;i<len;i++)
{
if(!used[i])
if(repeat!=nums[i])//repeat用完要归零,比如12345回退两位123xx,只要屏蔽第四位不是4就可以了,而且要归零,不然第五位也会屏蔽4
{
repeat = 256;//好吧,归零是不对的,当数组里出现0就呵呵了
used[i] = true;
path.Push(nums[i]);
bt(nums,used,path,len);
repeat=nums[i];//peek()一个数,如果这个数又被push进去了,就跳过
//找到问题出在哪了,当出现连退时,一个栈满了,出结果了,出去了,倒数第二位就也会从递归里出来
//我们只需要屏蔽最后一个出来的数就可以了,而且用完要归零
path.Pop();
used[i] =false;
}
}
}
}`
交换法
public class Solution {
int count = 0;
//string res = "";
List<string> res = new List<string>();
public string GetPermutation(int n) {
int[] nums = new int[n];
for(int i =1;i<=n;i++)
{
nums[i-1]=i;
}
perm(0,n,nums);
return res[k-1];
}
void perm(int start ,int end,int[] nums)
{
if(start==end)
{
string tmp = "";
for(int i =0;i<end;i++)
{
tmp+=nums[i];
}
res.Add(tmp);
//return;
}
if(start!=end)
for(int i = start;i<end;i++)
{
nums = swap(nums,start,i);
perm(start+1,end,nums);
count++;
}
}
int[] swap(int[] nums,int a,int b)
{
int tmp;
tmp = nums[a];
nums[a] = nums[b];
nums[b]= tmp;
return nums;
}
}