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;
    }