对分查找的最多次数_「剑指offer题解」数组中出现次数超过一半的数字
關注我——個人公眾號:后端技術漫談
我目前是一名后端開發工程師。主要關注后端開發,數據安全,網絡爬蟲,物聯網,邊緣計算等方向。
原創博客主要內容
- Java知識點復習全手冊
- Leetcode算法題解析
- 劍指offer算法題解析
- SpringCloud菜鳥入門實戰系列
- SpringBoot菜鳥入門實戰系列
- Python爬蟲相關技術文章
- 后端開發相關技術文章
image
前言
最近看了好多數據結構文章,但是數據結構拾遺系列遲遲憋不出,主要原因是很多數據結構其實非常偏門,不僅日常很難遇到,學起來還涉及很多數學模型,很難有快速的理解方法。
本著女排“短平快”的精神,先更新下劍指offer題解系列。
眾所周知,《劍指offer》是一本“好書”。
為什么這么說?因為在面試老鳥眼里,它里面羅列的算法題在面試中出現的頻率是非常非常高的。有多高,以我目前不多的面試來看,在所有遇到的算法體中,本書算法題出現的概率大概是60%,也就是10道題有6題是書中原題,如果把變種題目算上,那么這個出現概率能到達90%。
如果你是個算法菜雞(和我一樣),那么最推薦的是先把劍指offer的題目搞明白。
對于劍指offer題解這個系列,我的寫作思路是,對于看過文章的讀者,能夠做到:
- 迅速了解該題常見解答思路(偏門思路不包括在內,節省大家時間,實在有研究需求的人可以查閱其它資料)
- 思路盡量貼近原書(例如書中提到的面試官經常會要求不改變原數組,或者有空間限制等,盡量體現在代碼中,保證讀者可以不漏掉書中細節)
- 盡量精簡話語,避免冗長解釋
- 給出代碼可運行,注釋齊全,關注細節問題
題目介紹
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度為9的數組{1,2,3,2,2,2,5,4,2}。由于數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。
解題思路
方法一
思路
該方法改變了原數組。
首先要得到一個推論,那就是一旦有數字大于數組的一半,那么排序后的數組的中位數肯定是這個數字,那么我們就先找出這個數字。
這種算法是受快速排序算法的啟發。在隨機快速排序算法中,我們現在數組中隨機選擇一個數字,然后調整數組中數字的順序,使得比選中的數字小的數字都排在它的左邊,比選中的數字大的數字都排在它的右邊。如果這個選中的數字的下標剛好是n/2,那么這個數字就是數組的中位數。如果它的下標大于n/2,那么中位數應該位于它的左邊,我們可以接著在它的左邊部分的數組中查找。如果它的下標小于n/2,那么中位數應該位于它的右邊,我們可以接著在它的右邊部分的數組中查找。這是一個典型的遞歸過程
找到這個數字后,再判斷他是否符合條件(大于數組的一半),因為很有可能他是數組中出現次數最多的,但是未必大于數組的一半。
詳細細節見代碼注釋。
代碼
public class Solution { public int MoreThanHalfNum_Solution(int [] array) { if(array.length<=0) { return 0; } int start = 0; int length = array.length; int end = length-1; // 右移1位,相當于除2,效率更高 int middle = length>>1; // 當前位置 int index = Partition(array,start,end); // 直到取到中位數,才是結果 while(index!=middle){ if(index>middle){ index = Partition(array,start,index-1); } else{ index = Partition(array,index+1,end); } } int result = array[middle]; // 需要統計該數字個數,必須要大于數組長度的一半才能算 int times = 0; for(int i=0;iflag){ end--; } swap(array,start,end); while(array[start]<=flag){ start++; } swap(array,start,end); } return start; } private void swap(int[] array, int num1, int num2){ int temp = array[num1]; array[num1] = array[num2]; array[num2] = temp; }}方法二:兩兩消除
思路
該方法不改變原數組。
如果有符合條件的數字,則它出現的次數比其他所有數字出現的次數和還要多。
在遍歷數組時保存兩個值:
- times:次數
- result:當前數字
遍歷下一個數字時,若它與之前保存的數字相同,則次數加1,否則次數減1;若次數為0,則保存下一個數字,并將次數置為1。
遍歷結束后,所保存的數字即為所求。
之后,還要再判斷它是否符合大于數組的一半。
詳細細節見代碼注釋。
代碼
public int MoreThanHalfNum_Solution(int [] array) { int length = array.length; // 檢測數組是否為空 if (length == 0){ return 0; } // 初始化result和times參數 int result = array[0]; int times = 1; //遍歷數組(由于初始化過,所以直接從第二個數字開始) for(int i=1;i方法三:hashmap
思路
將數組中的數字依次遍歷,并寫入hashmap中,hashmap的值是該數字出現的次數,并在每次循環中判斷是否該數次數大于數組的一半,若有直接返回數字,否則遍歷完數組返回0。
代碼
思路簡單,代碼略。
總結
三種方法時間復雜度都是O(n)
關注我
我是一名后端開發。主要關注后端開發,數據安全,爬蟲等方向。微信:yangzd1102
Github:@qqxx6661
個人博客:
CSDN:@qqxx6661知乎:@Zhendong簡書:@蠻三刀把刀掘金:@蠻三刀把刀原創博客主要內容
Java知識點復習全手冊Leetcode算法題解析劍指offer算法題解析SpringCloud菜鳥入門實戰系列SpringBoot菜鳥入門實戰系列Python爬蟲相關技術文章后端開發相關技術文章個人公眾號:后端技術漫談
如果文章對你有幫助,不妨收藏起來并轉發給您的朋友們~
總結
以上是生活随笔為你收集整理的对分查找的最多次数_「剑指offer题解」数组中出现次数超过一半的数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Idea Maven报错找不到程序包
- 下一篇: 文本编码解释