Java O(1)空间和O(n)时间中的布尔数组重排序
问题来自: 给定一个包含n个具有布尔值键的对象的数组,请对该数组重新排序,以便首先显示键为false的对象键为true的对象的相对顺序不应改变。使用O(1)额外的空间和O(n)时间 我做了以下工作,它保留了对象的相对顺序,并使用了O(1)个额外的空间,但我相信它的时间复杂性是O(n*n!)Java O(1)空间和O(n)时间中的布尔数组重排序,java,arrays,algorithm,Java,Arrays,Algorithm,问题来自: 给定一个包含n个具有布尔值键的对象的数组,请对该数组重新排序,以便首先显示键为false的对象键为true的对象的相对顺序不应改变。使用O(1)额外的空间和O(n)时间 我做了以下工作,它保留了对象的相对顺序,并使用了O(1)个额外的空间,但我相信它的时间复杂性是O(n*n!) publicstaticvoid变量4(Boolean[]a){ int lastFalseIdx=0; for(int i=0;ilastFalseIdx){ 交换(a、falseIdx、falseIdx-
publicstaticvoid变量4(Boolean[]a){
int lastFalseIdx=0;
for(int i=0;ilastFalseIdx){
交换(a、falseIdx、falseIdx-1);
假IDX-;
}
lastFalseIdx++;
}
}
}
有人知道如何在O(n)时间内解决它吗
每次迭代后,
lastTrue
之后的所有元素均为true。没有两个true元素被交换,因为如果在i
和lastTrue
之间有一个true元素,它可能已经遇到并移到lastTrue
后面。这在O(n)
时间和O(1)
内存中运行。让数组有基于0的索引,并让它有n
元素。然后可以执行以下操作(下面的伪代码)
时间复杂度为
O(n)
,额外的空间仅用于两个变量i
和j
,因此内存为O(1)
。通过这种方式,在假值和真值之间保留排序。(此方法首先放置真实值,您可以根据需要更改它)。观察固定k的2k是O(1),2n是O(n)。构造第二个数组,将元素从源数组复制到目标数组,在一端添加keyfalse
,在另一端添加keytrue
的元素。您可以扫描数组一次,以确定边界必须位于何处。Java
code-如果您使用的是Boolean[]
-对象:
时间-O(1),空间-O(1)
Java
code-如果您使用的是boolean[]
-原语:
时间-O(N),空间-O(1)
OP需要额外的O(1)个空间。如何在O(1)空间中创建附加数组。k指的是什么?是的,保留顺序,但数组以真值开始,而不是假值。(也许在O(n)时间内反转它就可以了?)只需从前到前而不是从前到后进行测试,或者只需测试假值而不是真值。将[i]为真时的
更改为[i]为假时的
@ubica:Nope。这将保留假键元素的顺序,同时将它们放在开头。您要做的是保留设置了真键的元素的顺序,同时将它们放在末尾。将true
替换为false
。这不是对一些真值进行了重新排序吗?您需要插入而不是交换,不是吗?数组包含带有布尔字段的对象。整个对象需要交换到新的位置,而不仅仅是真值。“给定一个由n个对象组成的数组,其中包含布尔值键“@EdwardDoolittle你是对的,我将问题标题读为Boolean[]
。它不保留顺序。我知道布尔太原始了,看不到不保持真实元素顺序的后果。非常好!干净高效!OP只要求保留真值之间的相对顺序。@Ricky。在任何情况下,我们谈论的都是Java,所以int(和数组大小)被限制为32位,所以假设对单个数字的操作和内存是恒定的,这更有用也更简单。@Ricky是的,这取决于您想要使用的计算模型。事实证明,对于各种各样的算法,假设单个整数占用O(1)空间和O(1)时间进行简单算术运算是最有用的。因此,对于许多问题,假设<代码>减少(ARR,(t,e)-t+e)< /代码>为O(n)是完全好的,虽然是的,你也可以与O(nm)的M是位大小-并且对于一些问题,这确实会有很大的差异。少思考,少困惑。密切相关,。虽然此代码可以回答问题,但提供有关如何和/或为什么解决问题的附加上下文将提高答案的长期价值。
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++;
}
}
}
boolean array[n]; // The array
int lastTrue = n;
for (int i = n-1; i >= 0; --i) {
if (array[i]) {
swap(array[--lastTrue], array[i]);
}
}
// A[] is your array
i = 0
k = 0
for i from 0 to n-1
if A[i] is true
swap A[i] and A[k]
increment k
public static <T> void swap(T[] a, int i, int j) {
T t = a[i];
a[i] = a[j];
a[j] = t;
}
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;
}
def "reorder bools - objects"() {
given:
Boolean[] b = [false, true, true, true, false, true]
when:
getReorderBoolObjects(b)
then:
b == [false, false, true, true, true, true]
}
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;
}
def "reorder bools - primitives"() {
given:
boolean[] b = [false, true, true, true, false, true]
when:
getReorderBoolPrimitives(b)
then:
b == [false, false, true, true, true, true]
}
public static void rearrange(boolean[] arr) {
int invariant = arr.length-1;
for (int i = arr.length -1; i >= 0; i --) {
if ( !arr[i] ) {
swap( arr,i,invariant);
invariant--;
}
}
}
private static void swap(boolean arr[] , int from ,int to){
boolean temp = arr[from];
arr[from]=arr[to];
arr[to]=temp;
}