[英]Finding Second Smallest Element in Array
我試圖僅使用n + ceil(lg n) - 2
比較找到n個元素數組中的第二個最小元素。 CLRS中的暗示說要找到最小的元素。
這需要n - 1
比較,所以我留下ceil(lg n) - 1
比較找到第二個最小的,一旦我知道最大的。
有任何想法嗎?
謝謝,
bclayman
假設我們有一個列表1 ... a n,其中n
是2的冪。
首先將元素對起來,假設1為2 ,a 3為4 ,依此類推,並將它們相互比較。 這給你n/2
比較。
將所有獲勝者推進到下一輪,現在只有n/2
元素,並重復相同的過程。 這需要進行n/4
次比較。
重復上述步驟,直到你只剩下1個元素,最終獲勝者。 要到達那里你必須進行n/2 + n/4 + ... + 1 = n-1
比較。
這很棒,但哪一個可能是第二小? 好吧,它必須是你的贏家在前往頂峰的過程中擊敗的元素之一。 還有lg n
這樣的失敗者,所以你需要比較他們彼此之間尋找最小(需要進一步的lg n - 1
的比較)。
最小的輸家是整體排名第二的。
很容易證明為什么上面的方法總能找到第二小的:因為它比每個元素都小,但最終的贏家,除了冠軍之外,它將贏得每一輪。
如果n
不是2的冪,那么過程幾乎完全相同,除了輸入的列表將與下一個精確的2的冪一樣長,這就是為什么你最終得到ceil(lg n)
。
這是JavaScript中的基本實現,但並不確定它在所有情況下都完全尊重您的O()要求。 初始數組也會影響比較計數。
var elements = [ 12, 1 , 3, 4, 65, 7, -43, 8, 3, 8, 45, 2 ]; var nCompare = 0; var smallest = elements[0], smaller = elements[0]; for(var i = 1; i < elements.length; ++i) { ++nCompare; if(elements[i] < smaller) { ++nCompare; if(elements[i] < smallest) { smaller = smallest; smallest = elements[i]; } else smaller = elements[i]; } } document.body.innerHTML = '<pre>\\n' + 'Elements: [ ' + elements.join(', ') + ' ]\\n' + '# element: ' + elements.length + '\\n' + '\\n' + 'Smallest: ' + smallest + '\\n' + '2nd smallest: ' + smaller + '\\n' + '# compare: ' + nCompare + '</pre>';
以下是Java中具有O(n)復雜度的解決方案:
public class MainClass {
public static void main(String[] args) {
int[] a = { 4, 2, 8, -2, 56, 0 };
c(a);
}
private static void c(int[] a) {
int s = Integer.MAX_VALUE;
int ss = Integer.MAX_VALUE;
for (int i : a) {
if (i < s) {
ss = s;
s = i;
} else if (i < ss) {
ss = i;
}
}
System.out.println("smallest : " + s + " second smallest : " + ss);
}
}
輸出:最小:-2秒最小值:0
我認為他們不需要進行cel(log n)-1的額外比較,因為它只能在O(n)中完成,即在一次掃描中借助於下面給出的額外變量: -
for(i,0,no_of_elem-1)
{
if(min>elem[i])
{
second_smallest=min;
min=elem[i];
}
}
您只需將先前的最小值存儲在變量中,因為在掃描所有元素后,這將是您的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.