Arrays 面试测试-重新排列数组
可能重复:Arrays 面试测试-重新排列数组,arrays,algorithm,Arrays,Algorithm,可能重复: 在给定的元素数组中,如[a1,a2,a3,…an,b1,b2,b3,…bn,c1,c2,c3,…cn]编写一个程序来合并它们,如[a1,b1,c1,a2,b2,c2,…an,bn,cn]。 我们必须在额外的空间里做这件事 示例测试用例: Input #00: {1,2,3,4,5,6,7,8,9,10,11,12} Output #00: {1,5,9,2,6,10,3,7,11,4,8,12} Explanation: Here as you can notice, t
在给定的元素数组中,如[a1,a2,a3,…an,b1,b2,b3,…bn,c1,c2,c3,…cn]编写一个程序来合并它们,如[a1,b1,c1,a2,b2,c2,…an,bn,cn]。 我们必须在额外的空间里做这件事 示例测试用例:
Input #00:
{1,2,3,4,5,6,7,8,9,10,11,12}
Output #00:
{1,5,9,2,6,10,3,7,11,4,8,12}
Explanation:
Here as you can notice, the array is of the form
{a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4}
编辑:
我是在亚马逊考试中得到的。我已经试了很长时间了。
请提供psuedo代码。我尝试的是为第二个元素e找到新的位置p(第一个元素已经在正确的位置),在p处插入e,并对位置p处的旧元素重复相同的操作。但这是一个循环。
我尝试检测循环并将起始位置增加1。但即使这样也行不通
编辑2:
#include <iostream>
using namespace std;
int pos(int i, int n)
{
if(i<n)
{
return 3*i;
}
else if(i>=n && i<2*n)
{
return 3*(i-n) + 1;
}
else if(i>=2*n && i<3*n)
{
return 3*(i-2*n) + 2;
}
return -1;
}
void printn(int* A, int n)
{
for(int i=0;i<3*n;i++)
cout << A[i]<<";";
cout << endl;
}
void merge(int A[], int n)
{
int j=1;
int k =-1;
int oldAj = A[1];
int count = 0;
int temp;
while(count<3*n-1){
printn(A,n);
k = pos(j,n);
temp = A[k];
A[k] = oldAj;
oldAj = temp;
j = k;
count++;
if(j==1) {j++;}
}
}
int main()
{
int A[21] = {1,4,7,10,13,16,19,2,5,8,11,14,17,20,3,6,9,12,15,18,21};
merge(A,7);
cin.get();}
#包括
使用名称空间std;
内部位置(内部i,内部n)
{
如果(i=n&&i=2*n&&i这是像你这样的问题的一般解决方案
首先,对于每个源索引,您都知道目标索引。现在,您可以这样做:
拿第一个项目。找到它的最终位置。在该位置记住该项目,并将第一个项目存储在那里。现在,找到记住的项目所属的位置,并将该项目放在那里,记住替换的项目。继续此过程,直到它到达第一个项目的位置(显然)
如果已替换所有项目,则完成。如果未替换,则取第一个未转移的项目,从该项目开始,继续重复步骤1中的步骤
您需要标记已转移的项目。有不同的方法:例如,您可以使用项目存储中的一位
好的,上面的解决方案并不完全是O(1),因为它需要N
额外的位。下面是O(1)解决方案的概要,尽管效率较低:
考虑项目a1、b1、c1。它们需要位于结果的前3个位置。因此,我们正在执行以下操作:记住a1、b1、c1,将数组压缩到后面,但这三个项目除外(看起来是这样的:、a2、a3、…、an、b2、b3、…、bn、c2、c3、…、cn),并将项目a1、b1、c1放在开头的位置。现在,我们找到了前3个项目的位置,因此继续a2、b2、c2等的此过程
编辑:
让我们考虑上面的概要的时间复杂度,表示列表大小<代码> 3 *N/COD>。我们需要<代码> N< /代码>步骤。列表中的每一个单元格的压缩都可以一次完成,因此是<代码> O(n)< /代码>。步骤中的所有其他操作都是<代码> O(1)< /代码>,所以我们完全得到代码> n*o(n)=O(n ^ 2)。
复杂性。这远不是最好的解决方案,但是,正如@yiu_H提到的,线性时间解决方案需要大量使用或多或少的高等数学。我找不到任何O(n)算法,但这是O(n^2)在第一种情况下,每次代码通过给定的输入进行测试时,我都会将三元组移到最后一个,以C#为单位,可能有问题,如果有问题,请告诉我:
int[] a = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
int m = a.Length / 3;
int firstB = a[m];
for (int i = m-1; i > 0; i--)
{
int second = a[3 * m - 3];
int third = a[3 * m - 2];
//a[i + 2 * m] = a[i +2 * m];
a[3 * m - 2] = a[2 * m - 1];
a[3 * m - 3] = a[m - 1];
for (int j = m - 1; j < 2 * m - 1; j++)
{
a[j] = a[j + 1];
}
for (int j = 2 * m - 2; j < 3 * m - 3; j++)
{
a[j] = a[j + 2];
}
a[3 * m - 5] = second;
a[3 * m - 4] = third;
m--;
}
a[1] = firstB;
int[]a=新[]{1,2,3,4,5,6,7,8,9,10,11,12};
int m=a.长度/3;
int firstB=a[m];
对于(int i=m-1;i>0;i--)
{
int second=a[3*m-3];
第三个整数=a[3*m-2];
//a[i+2*m]=a[i+2*m];
a[3*m-2]=a[2*m-1];
a[3*m-3]=a[m-1];
对于(int j=m-1;j<2*m-1;j++)
{
a[j]=a[j+1];
}
对于(int j=2*m-2;j<3*m-3;j++)
{
a[j]=a[j+2];
}
a[3*m-5]=秒;
a[3*m-4]=第三;
m--;
}
a[1]=firstB;
这里有x*y编号:
a_11, a_12, ..., a_1x,
a_21, a_22, ..., a_2x,
...
a_y1, a_y2, ..., a_yx
然后,数字a_ij在数组中具有索引i*x+j
在您的程序之后,新的索引将
j * y + i
在你的面试中
{a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4}
x是4,y是3
因此,对于索引“n”
现在,您可以使用i,j,x,y
计算新索引
祝你好运。这是所谓的就地洗牌算法,如果你想高效地完成这项任务,这是一项非常艰巨的任务。我只是发布了这篇文章,这样人们就不会发布所谓的“解决方案”,声称它可以扩展到O(1)空间,而没有任何证据 当列表的形式为:
a1a2a3…anb1b2b3..bn
时,下面是一篇简单案例的论文:
以下是一个具有3个额外空间元素和O(n^2)复杂度的算法描述:
sa
、sb
、sc
分别是a
、b
和c
序列的下一个源索引。
d
是拷贝目的地索引
在每本书上:
- 将
、sa
和sb
处的元素复制到临时存储器中sc
- 将数组元素向左移动,以填充现在空缺的索引
、sa
和sb
sc
- 这将在
d
- 将三个元素从临时存储复制到空位置
#包括
#定义n4
INTA[]={1,2,3,4,5,6,7,8,9,10,11,12};
无效的
重排
{
int i;
int d;
int sa、sb、sc;
int-tmp[3];
d=0;
sa=0;
sb=sa+N;
sc=sb+N;
而(scsb+1;--i)
a[i]=a[i-1];
对于(i=sb+1;i>sa+2;--i)
a[i]=a[i-2];
sa+=3;
sb+=2;
sc++;
/*抄送*/
a[d++]=tmp[0];
a[d++]=tmp[1];
a[d++]=tmp[2];
}
}
int
主要()
{
int i;
重新安排
i = (n - (n % 4)) / 4;
j = n % 4;
First iteration:
copy to tmp: ., 2, 3, 4, ., 6, 7, 8, .,10,11,12
1 5 9
shift: ., ., ., 2, 3, 4, 6, 7, 8,10,11,12
copy to dst: 1, 5, 9, 2, 3, 4, 6, 7, 8,10,11,12
Second iteration:
copy to tmp: 1, 5, 9, ., 3, 4, ., 7, 8, .,11,12
2 6 10
shift: 1, 5, 9, ., ., ., 3, 4, 7, 8,11,12
copy to dst: 1, 5, 9, 2, 6,10, 3, 4, 7, 8,11,12
Third iteration:
copy to tmp: 1, 5, 9, 2, 6,10, ., 4, ., 8, .,12
3 7 11
shift: 1, 5, 9, 2, 6,10, ., ., ., 4, 8,12
copy to dst: 1, 5, 9, 2, 6,10, 3, 7 11, 4, 8,12
#include <stdio.h>
#define N 4
int a[] = {1, 2,3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
void
rearrange ()
{
int i;
int d;
int sa, sb, sc;
int tmp [3];
d = 0;
sa = 0;
sb = sa + N;
sc = sb + N;
while (sc < N*3)
{
/* Copy out. */
tmp [0] = a [sa];
tmp [1] = a [sb];
tmp [2] = a [sc];
/* Shift */
for (i = sc; i > sb + 1; --i)
a [i] = a [i - 1];
for (i = sb + 1; i > sa + 2; --i)
a [i] = a [i - 2];
sa += 3;
sb += 2;
sc++;
/* Copy in. */
a [d++] = tmp [0];
a [d++] = tmp [1];
a [d++] = tmp [2];
}
}
int
main ()
{
int i;
rearrange ();
for (i = 0; i < N*3; ++i)
printf ("%d\n", a [i]);
putchar ('\n');
return 0;
}