查找算法——找到序列中第二大的數(修正版)


今天來說一個簡單的需求:在一個序列中找到第二大的元素。

一眼看到這個問題,感覺解決的方法有很多,因為這並不是一個困難的問題。隨便一想,能有下面幾種解法:

1 首先排序,然后取第二個位置的元素

2 循環遍歷元素序列,找到最大的元素,然后將其移除。再重復此過程,得到第二大的元素

當然還有其他的思路,這里就不一一列舉了。如果大家有什么好的想法,可以給我留言,咱們一起探討。

 

仔細分析一下,不難發現,上面的方法雖然可以達到目的,但是效率都不高。第一種方法相當於一次排序過程,最快也要O(nlogn)的時間才能完成。而第二種方法需要循環遍歷序列兩次,O(n)+O(n)的時間復雜度雖然不是無法接受,但畢竟還是要循環兩次。對於我們寫軟件的人來說,顯然希望代碼是“完美”的。因此在這里,提出一個只循環一次的方法,供大家借鑒參考。如果大家有好方法,歡迎提出。

廢話不說,下面介紹算法思路:

我們既然可以循環遍歷一次得到最大的元素,為什么不能保存住第二大的元素呢?當然可以,我們在比較元素大小時,只要把小的保存起來,經過一遍循環,這個元素就是第二大的元素了

代碼就更簡單了

int find_second_biggest(vector<int> &v){
int len = v.size();
int max,second;
if (len < 2){
return -1;
}
if (v[0]>v[1]){
second = v[1];
max = v[0];
}
else{
second = v[0];
max = v[1];
}
for (int i=2; i< len; i++){
if(max < v[i]){
second = max;
max = v[i];
}
else if (second < v[i]){
second = v[i];
}
}
return second;
}

相信看過代碼,大家更清楚了吧,是不是很簡單,而且只用了一次循環。這個問題很簡單,寫這個的目的就是要提醒自己,遇到問題要先多想一想,而不是一味的使用簡單暴力的方法,多想半個小時有時會省上一天甚至更多的時間。

當然這個方法不一定是最好的,希望大家多多拍磚。

后記:之前提交了一個有錯誤的版本,可以說是給自己一個教訓,還沒有進行測試就放了上去,以至於犯了一個很基本的錯誤。看來以后還是要多試一下,不能太盲目自信了。這個版本是經過測試的,應該是個可用版本。如果大家發現有什么數據會導致錯誤,歡迎再指出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM