我有一个程序可以找到数组的两个最大元素。我必须查看数组元素之间的比较次数以确定效率(不是大O)我已经确定最坏情况是2n-3比较(假设前两个元素是最大的)这是函数。
Integer[] A = {11,22,8,7,5,6,7,8,1,9};
int largest = 0;
int secondLargest = 0;
int count = 1;
if (A[0] < A[1]){
largest = A[1];
secondLargest = A[0];
} else {
largest = A[0];
secondLargest = A[1];
}
for (int i = 2; i < A.length; i++){
count++;
if (A[i] > largest) {
secondLargest = largest;
largest = A[i];
} else {
count++;
if (A[i] > secondLargest) {
secondLargest = A[i];
}
}
}
System.out.println("Largest:" + largest + " Second:" + secondLargest + " count:" + count);
我使用count来确定比较次数。 有没有办法减少这个函数中最坏情况比较的次数?我无法弄清楚如何使这个功能更好。
答案 0 :(得分:2)
2n - 3
(通过1 + 2(n-2)
)最糟糕的情况就是尽可能好:您必须查看所有n
值,并且每个值都必须在最坏的情况下检查2
最大值。
如果换掉支票,你可以获得一些效率:
if ( A[i] > secondLargest )
{
if ( A[i] > largest )
secondLargest = largest,
largest = A[i];
else
secondLargest = A[i];
}
因为如果某个值不高于secondLargest,则它不会大于最大值。在最佳案例场景(降序排序列表)中,这会将效率提高到n - 3
,而您的算法在此处也有2n - 3
。
但是,最坏的情况(升序排序列表)仍然是相同的。
答案 1 :(得分:1)
无论您选择何种算法,您都可以想出每个元素必须与最大和第二大元素进行比较的场景。
然而,在更常见的随机分布案例中,您可以通过首先与第二大值进行比较来避免大量比较。大多数元素将小于第二大值,并将避免第二次比较。
if (value > secondLargest) {
secondLargest = value;
if (secondLargest > largest) {
int temp = largest;
largest = secondLargest;
secondLargest = temp;
}
}
或更好(IMO):
int[] largest = new int[2];
for (int value: A) {
if (value > largest[1]) {
largest[1] = value;
Arrays.sort(largest);
}
}
请注意,对于小型数组Arrays.sort
,只需进行简单的比较和交换。