下面的代码,它应该是O(n)。 有两个循环,我知道这个。但这并不一定意味着它是O(n ^ 2)。函数循环的运行时间不会超过n + 1次(至少据我所知!)。那应该是O(n)。我错了吗?有人可以帮我吗?谢谢!
编辑:程序将奇数整数放在前面,甚至整数放在数组的后面!
public class Main {
public static void main(String[] args) {
int[] array = new int[]{5, 4, 3, 2, 1, 0};
organizeArray(array);
for (int j = 0; j < array.length; j++) {
System.out.println(array[j]);
}
}
public static void organizeArray(int[] array) {
int end = array.length - 1;
for (int i = 0; i < array.length; i++) {
int temp = 0;
while (true) {
if (i == end)
break;
if (array[i] % 2 == 0) {
temp = array[i];
array[i] = array[end];
array[end] = temp;
end = end - 1;
}
if (array[i] % 2 != 0)
break;
}
if (i == end)
break;
}
}
}
答案 0 :(得分:0)
有趣的代码。当i
&#39;元素为奇数时,内部for循环将中断。如果它不是奇数,那么它将交换end
中的元素,直到找到奇数。由于end
在每次交换时递减,并且程序在i
到达end
时完成,因此i
或end
可以分别在GC.Collect();
GC.WaitForPendingFinalizers();
或GC.GetTotalMemory(false) // do not wait for GC
递增/递减大多数O(n)次。因此,并且因为循环中的所有其他操作都是O(1),所以尽管存在嵌套循环,程序确实在时间O(n)中运行。
答案 1 :(得分:0)
由于other question与此版本重复,请允许我在此处发布我的答案。
当您增加i
或减少end
时,代码为O(n)。在任何情况下,你将其余的工作(n)减少一个。
对于即将到来的作业:您可以通过尝试轻松测试您对big-O的看法。大多数情况下,测试的数量并不需要非常大。这不是证据,但如果你的想法是正确的,它会给你一个很好的暗示。
这是我的100个测试问题的代码。它产生100对数字:数组的长度和循环的数量。您将此列表带到图表中。
public class Main {
public static void main(String[] args) {
Main main = new Main();
Random random = new Random();
for (int i = 0; i < 100; i++) {
int[] array = new int[random.nextInt(10000 - 10) + 10]; // between 10 and 9999 numbers long
for (int j = 0; j < array.length; j++) array[j] = random.nextInt();
main.organize(array);
}
}
private int[] organize(int[] array) {
long loops = 0;
int end = array.length-1;
// I've shorten your code here. This does the same with less breaks
for (int i = 0; i < end; i++) {
while(i < end && array[i] % 2 == 0) {
swap(array, i, end--);
loops++;
}
}
System.out.printf("%d\t%d\n", array.length, loops);
return array;
}
private void swap(int[] array, int a, int b) {
int t = array[a];
array[a] = array[b];
array[b] = t;
}
}
图表看起来像一条直线。所以你的证明应该是O(n),对吧?