从给定数组输入转换到另一个数组的最小移动量

时间:2019-06-11 18:23:21

标签: java arrays algorithm

我有一个source数组[2, 5, 0, 1, 7],现在在此数组中,要求说我可以将数组中的值0用作占位符,可以用来交换元素仅靠1位置left or right

Eg: moving right the array [2, 5, 0, 1, 7] results in [2, 5, 1, 0, 7]
Eg: moving left the array [2, 5, 0, 1, 7] results in [2, 0, 5, 1, 7]

如果值0的索引位于startingending的位置,则它将旋转到next索引。

也就是说,如果值0的索引位于array.length,那么向右移动会将其定位在array[0]

Eg: moving right the array [2, 5, 7, 1, 0] results in [0, 2, 5, 7, 1]

类似地,如果值0在数组的索引0上,那么向左移动将与array[array.length]交换

Eg: moving left the array [0, 5, 7, 1, 2] results in [5, 7, 1, 2, 0]

现在找到将源数组转换为给定的destination数组[0, 2, 5, 1, 7]所需的最少步骤。

Step 1: move 0 from index 2 to index 1 and swap elements

[2, 0, 5, 1, 7]

Step 2: move 0 to left postion
[0, 2, 5, 1, 7]

For this question, the answer should be 2.

问题的签名看起来像这样:

public int getMinimumMoves(int[] a, int[] b) {

}

我有以下方法,但时间复杂度更高。

  

方法1:将数组a向右移动,直到a.length次,然后   验证它是否与数组b匹配。

     

方法2:向左移动数组a直到a.length次,然后   验证它是否与数组b匹配。

获取以上两种方法中的最小值。另外,在这种情况下,代码应返回-1。有可能无法解决。

请让我知道解决此问题的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

验证数组的大小相同:

int size = a.size();
if (size != b.size()) return -1; //size mismatch

重建不带0的数组并进行比较:

int[] c = new int[size - 1];
int[] b = new int[size - 1];
int aIndex = -1;
int bIndex = -1;
for (int i = 0; i < size; ++i) {
    if (a[i] == 0) {
        if (aIndex >= 0) return -1; //second occurrence of 0 in a
        aIndex = i;
    }
    else c[aIndex < 0 ? i : i - 1] = a[i];
    if (b[i] == 0) {
        if (bIndex >= 0) return -1; //second occurrence of 0 in b
        bIndex = i;
    }
    else d[bIndex < 0 ? i : i - 1] = b[i];
}
for (int i = 0; i < size - 1; ++i) {
    if (c[i] != d[i]) return -1; //comparison fails
}
if (aIndex < 0 || bIndex < 0) return -1; //0 not present in a or b

返回零索引之间的差(在圆形数组中):

return Math.min(Math.abs(aIndex - bIndex), Math.abs((aIndex + size) % size) - bIndex);

运行时为O(大小)。