给定一个数组[a1b2c3d4]转换为[abcd1234]

时间:2012-10-02 02:23:37

标签: java arrays algorithm array-algorithms

约束:

  1. O(1)空间
  2. O(n)时间
  3. 这不是一个家庭作业问题,只是我遇到的一个有趣的问题。

    以下是我能想到的一些解决方案,但在给定约束条件下没有任何解决方案。

    方法1

    *使用O(n)内存*

    • 递归地将数组分为两部分。 (保持划分直到每个子问题的大小<= 2)
    • 首先用数组排序每个子问题,然后用数字排序。
    • 合并子问题数组

    方法2

    在O(n log n)时间

    • 按照字典顺序对数组进行排序,它变为1234abcd
    • 反转阵列4321dcba的两半
    • 反转整个字符串abcd1234

    方法3

    如果定义了数字范围

    如果情况是数字在特定范围内,那么我可以初始化一个int say track = 0; 当我遇到数组中的数字时,设置适当的位 例如(1 <&lt; a [2])。 1.将字母交换到数组的前半部分 2.在轨道变量中标记数字 3.稍后使用轨道填充数组的后半部分。

    方法4 如果我们想要删除整数范围的约束,那么我们可以将方法3与HashMap一起使用,但是它需要更多的内存。

    想不出更好的方法来解决O(1)时间和O(n)空间中的泛型问题。

    这里的一般问题是指:

    给定序列x1y1x2y2x3y3 .... xnyn         其中x1,x2是字母x1&lt; x2&lt; ....&lt; XN         和y1y2 ... yn是整数。 y1&lt; y2&lt; ....&lt; YN 将输出排列为x1x2 ... xny1y2 ... yn

    有什么建议吗?

4 个答案:

答案 0 :(得分:6)

什么是n?假设n是输入的大小:

这称为列表的卷积。实质上,您必须将对(a,1),(b,2),(c,3),(d,4)对列表转换为一对列表(a,b,c,d),(1,2,3,4)。它与矩阵的转置操作相同。

无论如何,您必须将结构视为k维数组,其中k = lg n。当你在索引i“移动”索引i按位旋转时,你得到的数组的卷积。在这种情况下,我们希望将索引向右旋转1位。这意味着卷积是一个最大周期长度为k的置换。然后诀窍是从每个循环中选择一个索引 - 这将始终包括0和n-1。

编辑:实际上,你可能想要的是将排列分解为换位的产物。然后,您需要做的只是交换。

答案 1 :(得分:0)

或者,您可以使用强大的Python,并将其转换为java:

a = [1,'a',2,'b',3,'c',4,'d']
a = a[0:len(a):2] + a[1:len(a):2]
print(a) #this will print [1,2,3,4,'a','b','c','d']

答案 2 :(得分:0)

@coder 提到的循环前导算法有效。只需确保将数组拆分为 (3^n + 1) 的大小。应用循环前导算法,然后合并这些。

答案 3 :(得分:-3)

这是我在O(n)中的算法。

void cycle_leader(int * arr,int n) {

for (int i = 1; i < n / 2; i+= 2)
{
    int j = i;
    int save;
    int tmp = arr[i];

    do{
        if (j & 1) //odd index element
            j = n / 2 + j / 2;
        else
            j = j / 2;

        save = arr[j];
        arr[j] = tmp;
        tmp = save;
    } while(j != i);
}

}