【问题标题】:How to randomly re-insert an element in an array efficiently如何有效地在数组中随机重新插入元素
【发布时间】:2019-05-07 22:56:04
【问题描述】:

假设我们有一个整数数组int[] A = {1,2,3,4,5,6,7,8,9}

假设我们想从A 中选择一些随机整数,然后随机将其重新插入到数组的其他位置,如下所示:

先拍点int number = A[random.nextInt(A.length)]

假设我们随机选择5,然后在78之间随机重新插入,这样A就变成了{1,2,3,4,6,7,5,8,9}

现在,我们显然可以通过创建一些临时变量int temp = 5,将子数组{6,7} 向左移动,然后将5 重新插入到7 占用的索引中来重新插入之前。但是有没有一种更有效的方法来做到这一点而无需移动一些子数组(并且无需更改为另一个数据结构,如链表)?因为显然我们有一些O(n) 的最坏情况,我们随机选择A[0],然后必须将其插入A[A.length],需要移动数组中的所有元素,我不想这样做.

【问题讨论】:

  • 您可以查看System::arraycopy,它可以将srcdest 视为同一个数组。
  • “但是有没有更有效的方法来做到这一点,而无需移动一些子数组(并且无需更改为另一个数据结构,如链表)?” - 不。数组以连续的方式暴露给 Java 开发人员。所以你看到的是 O(n) 最坏的情况。

标签: java arrays random insert


【解决方案1】:

尚未对此进行大量测试,但这里有一个解决方案的快速草图。

/**
 * Shifts the element of the given {@code array} presently at index {@code fromIndex} to
 * {@code toIndex}.
 * 
 * @param array     the array whose elements should be shifted
 * @param fromIndex the current index of the element to shift
 * @param toIndex   the destination index of the element to shift
 */
public static void shift(final Object array,
                         final int fromIndex,
                         final int toIndex) {
    if (fromIndex == toIndex) {
        return;
    }

    final Object atIndex = Array.get(array, fromIndex);

    if (toIndex > fromIndex) {
        System.arraycopy(array, fromIndex + 1, array, fromIndex, toIndex - fromIndex);
    } else {
        System.arraycopy(array, toIndex, array, toIndex + 1, fromIndex - toIndex);
    }

    Array.set(array, toIndex, atIndex);
}

虽然 general 方法与您描述的差不多,但我怀疑System.arraycopy 的性能比(几乎)您将获得的任何其他方法都要好。不过我可能错了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 2012-08-30
    • 2010-09-08
    • 1970-01-01
    • 2014-07-13
    相关资源
    最近更新 更多