O(1) 空间和 O(n) 时间内的布尔数组重新排序 Java代码 - 如果您使用的是 - 对象:Boolean[] Java代码 - 如果您使用的是 - 基元:boolean[]

2022-09-01 11:56:44

这个问题取自编程访谈的元素

给定一个包含 n 个具有布尔值键的对象的数组 A,请对数组重新排序,以便首先显示键为 false 的对象。具有 key true 的对象的相对顺序不应更改。使用 O(1) 额外的空间和 O(n) 时间。

我做了以下操作,它保留了具有键 true 的对象的相对顺序,并使用 O(1) 额外的空间,但我相信它的时间复杂度是 O(n*n!)。

public static void rearrangeVariant4(Boolean[] a) {
  int lastFalseIdx = 0;
  for (int i = 0; i < a.length; i++) {
    if (a[i].equals(false)) {
      int falseIdx = i;
      while (falseIdx > lastFalseIdx) {
        swap(a, falseIdx, falseIdx-1);
        falseIdx--;
      }
      lastFalseIdx++;
    }
  }
}

有人知道如何在O(n)时间内解决它的想法吗?


答案 1
boolean array[n]; // The array
int lastTrue = n;
for (int i = n-1; i >= 0; --i) {
  if (array[i]) {
    swap(array[--lastTrue], array[i]);
  }
}

每次迭代后,之后的所有元素都为真。没有两个真正的元素被交换,因为如果和之间有一个真正的元素,它早就会遇到并移动到后面。这在时间和内存中运行。lastTrueilastTruelastTrueO(n)O(1)


答案 2

Java代码 - 如果您使用的是 - 对象:Boolean[]

时间 - O(1), 空间 - O(1)

public static <T> void swap(T[] a, int i, int j) {
    T t = a[i];
    a[i] = a[j];
    a[j] = t;
}

时间 - O(N), 空间 - O(1)

public static Boolean[] getReorderBoolObjects(Boolean[] array) {
    int lastFalse = 0;

    for (int i = 0; i < array.length; i++) {
        if (!array[i]) {
            swap(array, lastFalse++, i);
        }
    }

    return array;
}

Spock测试用例:

def "reorder bools - objects"() {
    given:
    Boolean[] b = [false, true, true, true, false, true]

    when:
    getReorderBoolObjects(b)

    then:
    b == [false, false, true, true, true, true]
}

Java代码 - 如果您使用的是 - 基元:boolean[]

时间 - O(N), 空间 - O(1)

public static boolean[] getReorderBoolPrimitives(boolean[] array) {
    int falseCount = 0;
    for (final boolean bool : array) {
        if (!bool) {
            falseCount++;
        }
    }
    for (int i = 0; i < array.length; i++) {
        array[i] = i >= falseCount;
    }
    return array;
}

Spock测试用例:

def "reorder bools - primitives"() {
    given:
    boolean[] b = [false, true, true, true, false, true]

    when:
    getReorderBoolPrimitives(b)

    then:
    b == [false, false, true, true, true, true]
}