昨晚试着写了下Permutation的代码,发现也是弄了一会儿才写对,主要是还要加一个参数k,不能只用一个n来递归,因为到底归结束的时候,我需要从原数组起点到重点
print所有的元素。另外看到老赵的微博说过,今天当年面试的人这么多年还是不会写permutation,而且还和网友激烈的针尖对麦芒,我在一旁冷眼旁观,如果从没看过这个算法,
要完全自己造轮子确实不好写的。
附上代码:
void PermutationTest(int*a, int k, int n)//permutate a[k...n-1]
{
if(k==n)//permutate array no elements
{
for(int i=0;i<n;i++)
cout<<a[i];
cout<<endl;
}
else
{
for(int i=k;i<n;i++)
{
swap(a[k],a[i]);
PermutationTest(a,k+1,n);
swap(a[k],a[i]);
}
}
}
另外再附上自己最近学习的带重复数的permutation,之前每次晚上走在回BLK942的路上都在想,但是一直是自己代码尝试的方法,测试有bug,一直没想清楚,今天晚上回去看了邹博的PPT瞬间明了,不是看a[k] a[i]是否相等,而是看a[i] 与a[k]...a[i-1] 是否相等,有相等,说明之前交换过这种的,再交换一定有重复的,例如第一个数和(后面4个,包括自己)交换, 1232 -> 2132 2231, 那么后面132 231一定都会重复出现6次permutation了,举这个例子。
所以价格判断函数就可以了,代码如下:
bool IsSwap(int *a, int i, int k) //whether a[k] has occured in a[i...k-1]
{
//bool flag=true;
for(int j=k;j<i;j++)
{
if(a[j]==a[i])
return false;
}
return true;
}
void permutation(int k, int n, int*a)
{
if(k==n)
{
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
else
{
for(int i=k;i<=n-1;i++)
{
if(!IsSwap(a, i, k))
continue;
swap(a[k],a[i]);
permutation(k+1,n,a);
swap(a[k],a[i]);
}
}
}
另外需要注意的是,permutaion(k,n) 里面k是数组第一个元素,0-base就是0,n可以是元素个数,也可以是最后一个元素index(邹博这么写的),而combination(selectk, k, selectn, n)是select k=0,选择k个元素,selectn=0,选择n个元素
本以为这样就可以刷几道leetcode题目,结果一看啥样,4道题目,1道3*,1道4* 2道5*,非递归版本,按某个顺序输出下一个等等,比这个复杂得多,我还是先多刷点容易题建立点信心,并积累点数量再说吧。。。