1. 程式人生 > >二分查詢,你真的掌握了嗎?

二分查詢,你真的掌握了嗎?

二分查詢,最基本的演算法之一,也是面試中常被考察的重點,因為基本的演算法最能反映出一個人的基礎是否紮實。本文對二分查詢相關題目做一個總結。

題目列表:

  1. int search(int A[], int n, int target)  
  2. {  
  3.     int low = 0, high = n-1;  
  4.     while(low <= high)  
  5.     {  
  6.         // 注意:若使用(low+high)/2求中間位置容易溢位
  7.         int mid = low+((high-low)>>1);   
  8.         if
    (A[mid] == target)  
  9.             return mid;  
  10.         elseif(A[mid] < target)  
  11.             low = mid+1;  
  12.         else// A[mid] > target
  13.             high = mid-1;  
  14.     }  
  15.     return -1;  
  16. }  

此題也就是求target在陣列中第一次出現的位置。這裡可能會有人想先直接用原始的二分查詢,如果不存在直接返回-1,如果存在,然後再順序找到這個等於target值區間的最左位置,這樣的話,最壞情況下的複雜度就是O(n)了,沒有完全發揮出二分查詢的優勢。這裡的解法具體過程請參考實現程式碼與註釋。

  1. int searchFirstPos(int A[], int n, int target)  
  2. {  
  3.     if(n <= 0) return -1;  
  4.     int low = 0, high = n-1;  
  5.     while(low < high)  
  6.     {  
  7.         int mid = low+((high-low)>>1);  
  8.         if(A[mid] < target)  
  9.             low = mid+1;  
  10.         else// A[mid] >= target
  11.             high = mid;  
  12.     }  
  13.     /*  
  14.     迴圈過程中,當low大於0時,A[low-1]是小於target的,因為A[mid] < target時, 
  15.     low=mid+1;當high小於n-1時,A[high]是大於等於target的,因為A[mid] >= target時, 
  16.     high = mid;迴圈結束時,low 等於 high,所以,如果A[low](A[high])等於target, 
  17.     那麼low(high)就是target出現的最小位置,否則target在陣列中不存在。 
  18.     */
  19.     if(A[low] != target)  
  20.         return -1;  
  21.     else
  22.         return low;  
  23. }  

此題也就是求target在陣列中最後一次出現的位置。與上一題基本一樣,但是有個地方要注意,具體請參考實現程式碼與註釋。

  1. int searchLastPos(int A[], int n, int target)  
  2. {     
  3.     if(n <= 0) return -1;  
  4.     int low = 0, high = n-1;  
  5.     while(low < high)  
  6.     {  
  7.         /* 
  8.         這裡中間位置的計算就不能用low+((high-low)>>1)了,因為當low+1等於high 
  9.         且A[low] <= target時,會死迴圈;所以這裡要使用low+((high-low+1)>>1), 
  10.         這樣能夠保證迴圈會正常結束。 
  11.         */
  12.         int mid = low+((high-low+1)>>1);  
  13.         if(A[mid] > target)  
  14.             high = mid-1;  
  15.         else// A[mid] <= target
  16.             low = mid;  
  17.     }  
  18.     /*  
  19.     迴圈過程中,當high小於n-1時,A[high+1]是大於target的,因為A[mid] > target時, 
  20.     high=mid-1;當low大於0時,A[low]是小於等於target的,因為A[mid] <= target時, 
  21.     low = mid;迴圈結束時,low 等於 high,所以,如果A[high](A[low])等於target, 
  22.     那麼high(low)就是target出現的最大位置,否則target在陣列中不存在。 
  23.     */
  24.     if(A[high] != target)  
  25.         return -1;  
  26.     else
  27.         return high;  
  28. }  

也就是求小於target的最大元素的位置。請參考實現程式碼與註釋。

  1. int searchLastPosLessThan(int A[], int n, int target)  
  2. {  
  3.     if(n <= 0) return -1;  
  4.     int low = 0, high = n-1;  
  5.     while(low < high)  
  6.     {  
  7.         int mid = low+((high-low+1)>>1); // 注意,不要導致死迴圈
  8.         if(A[mid] < target)  
  9.             low = mid;  
  10.         else// A[mid] >= target
  11.             high = mid-1;  
  12.     }  
  13.     /*  
  14.     迴圈過程中,當low大於0時,A[low]是小於target的,因為A[mid] < target時, 
  15.     low=mid;當high小於n-1時,A[high+1]是大於等於target的,因為A[mid] >= target時, 
  16.     high = mid-1;迴圈結束時,low 等於 high,所以,如果A[low](A[high])小於target, 
  17.     那麼low(high)就是要找的位置,否則不存在這樣的位置(A[0] >= target時)。 
  18.     */
  19.     return A[low] < target ? low : -1;  
  20. }  

也就是求大於target的最小元素的位置。請參考實現程式碼與註釋。
  1. int searchFirstPosGreaterThan(int A[], int n, int target)  
  2. {  
  3.     if(n <= 0) return -1;  
  4.     int low = 0, high = n-1;  
  5.     while(low < high)  
  6.     {  
  7.         int mid = low+((high-low)>>1);  
  8.         if(A[mid] > target)  
  9.             high = mid;  
  10.         else// A[mid] <= target
  11.             low = mid+1;  
  12.     }  
  13.     /*  
  14.     迴圈過程中,當low大於0時,A[low-1]是小於等於target的,因為A[mid] <= target時, 
  15.     low=mid+1;當high小於n-1時,A[high]是大於target的,因為A[mid] > target時, 
  16.     high = mid;迴圈結束時,low 等於 high,所以,如果A[high](A[low])大於target, 
  17.     那麼high(low)就是要找的位置,否則不存在這樣的位置(A[n-1] <= target時)。 
  18.     */
  19.     return

    相關推薦

    二分查詢真的掌握

    二分查詢,最基本的演算法之一,也是面試中常被考察的重點,因為基本的演算法最能反映出一個人的基礎是否紮實。本文對二分查詢相關題目做一個總結。 題目列表: int search(int A[], int n, int target)  

    這些Java基礎面試知識點掌握

    本文主要是我最近複習Java基礎原理過程中寫的Java基礎學習總結。Java的知識點其實非常多,並且有些知識點比較難以理解,有時候我們自以為理解了某些內容,其實可能只是停留在表面上,沒有理解其底層實現原理。 紙上得來終覺淺,絕知此事要躬行。筆者之前對每部分的內容 對做了比較深入的學習以及程式碼實

    10個用Java謀生非常有趣的方式全都掌握

    提升 ava ext 如果 cap suse 努力 混合 ges 令我驚訝的是,有些人覺得編程並不令人興奮——只將它當作是一份枯燥的工作。不過,雖然可能的確有很多無聊的編程工作,但這並不意味著你不得不接受這些工作中的一個。 程序員有各種各樣的機會,運用他們的技能去做一些有趣

    【Java8新特性】介面中的預設方法和靜態方法掌握

    ## 寫在前面 > 在Java8之前的版本中,介面中只能宣告常量和抽象方法,介面的實現類中必須實現介面中所有的抽象方法。而在Java8中,介面中可以宣告預設方法和靜態方法,本文,我們就一起探討下介面中的預設方法和靜態方法。 ## 介面中的預設方法 Java 8中允許介面中包含具有具體實現的方法,該

    PHP 高手應該掌握 10 項技能 get 到?(內附學習大綱)

    點選上方“CSDN”,選擇“置頂公眾號”關鍵時刻,第一時間送達!在過去的幾年中,PHP 工程師一

    VR禁毒體驗試過

    研發 img 成了 此舉 pict clas bsp 廣州 嘗試 VR禁毒體驗,你試過了嗎? 大家先來跟著小編的文字,嘗試冥想一下——當你正處於寧靜的情緒中,對於顏色感覺生動、豐富而深刻,感到周圍事物絢麗多彩,五光十色;對音樂的鑒賞能力增強,對其他聲音也很敏感。然後,感到時

    【項目管理】經驗之談 | 資深項目經理都避免的5個坑中招

    尊重 最終 fail 同方 快速 這就是 tro 理解 動力 哈嘍!大家好! 那天看到最有趣的一句話就是 為了填坑,一位項目經理胖了20斤 。。。。。 今天就給大家介紹一下 項目經理要註意的那些“坑” 項目經理“誤踩雷區” 1 未告知成員工作目標 作為項目經理

    C語言/原子/編譯真的明白

    clas done ati pre 內存 程序 導致 裏的 creat   說到原子,類似於以下的代碼可能人人都可以看出貓膩。 #include <stdio.h> #include <pthread.h> int cnt = 0;

    身份證掃描識別/身份證OCR識別的正確姿勢get到

    視頻流 開發包 掃描識別 出錯 應用 左右 信息 設備 ucs 自從國家規定電信實名制之後,實名制已經推廣到各個領域:辦理通信業務需要實名制、銀行開戶需要實名制、移動支付需要實名制,就連註冊個自媒體賬戶都需要實名制。 而實名制的背後,就是身份證信息的采集和錄入驗證。 傳統的

    IT輪子系列(六)——Excel上傳與解析一套代碼解決所有Excel業務上傳Get到

    tryparse mappath src 個推 列名 import ges bject tab 前言 在日常開發當中,excel的上傳與解析是很常見的。根據業務不同,解析的數據模型也都不一樣。不同的數據模型也就需要不同的校驗邏輯,這往往需要寫多套的代碼進行字段的檢驗,如必填

    柯夢嬌:3.5非農強勢來襲準備好

    均線 黃金 有效 走勢分析 body 現象 線圖 盈利 交易 柯夢嬌:3.5非農強勢來襲,你準備好了嗎? 就像貝利的烏鴉嘴一樣,資本市場常有些令人訝異的“規律”,比如期指“逢9必跌”、原油市場“7月必跌”等等。如今,在黃金市場上,也出現了這一種詭異的現象——周五總是

    python小白也可以分分鐘爬取微博數據並生成有個性的詞雲get到

    python 爬蟲 web開發 編程Python(發音:英[?pa?θ?n],美[?pa?θɑ:n]),是一種面向對象、直譯式電腦編程語言,也是一種功能強大的通用型語言,已經具有近二十年的發展歷史,成熟且穩定。它包含了一組完善而且容易理解的標準庫,能夠輕松完成很多常見的任務。它的語法非常簡捷和清晰,與其它大多

    共享人才時代已經到來做好準備

    共享共享經濟是一種全新的經濟模式,近幾年得到了突飛猛進的發展。其本質是整合線下的閑散物品或服務者,讓他們提供產品或服務。在共享過程中,供給方通過在特定時間內提供使用權或服務獲得酬勞,需求方雖無所有權但在特定使用權內滿足了需要。 人才是決定企業成敗的關鍵性因素之一。共享人才做為一種新生的力量,在互聯網大環境中扮

    記一次安裝多版本php的四個雷區踩著

    path start cgi 命令執行 mysq -c tool port 一鍵 記一次安裝多版本的php的四個雷區,你踩著了嗎 需求:公司需要在同一臺服務器上安裝不同版本的php,而這一臺的服務上已經安裝了php.7.1,現需要同

    逸管家:共享人才時代已經到來做好準備

    特定 正常 之間 結束 銷售 相關 不可 人的 十分 ?  共享人才時代已經到來,你做好準備了嗎? 共享經濟是一種全新的經濟模式,近幾年得到了突飛猛進的發展。其本質是整合線下的閑散物品或服務者,讓他們提供產品或服務。   在共享過程中,供給方通過在特定時間內提供使用權或服務

    初學C語言編程時最容易犯的錯誤踩坑

    不同的 類型 alt 結果 如何 wid text size can C編譯的程序對語法檢查並不像其它高級語言那麽嚴格,這就給編程人員留下“靈活的余地”,但還是由於這個靈活給程序的調試帶來了許多不便,尤其對初學C語言的人來說,經常會出一些連自己都不知道錯在哪裏的錯誤。看著有

    HTTPS時代已來做好準備

    兩種方法 運營商 增長 images 同步 有效期 很多 取證 錯誤類型 摘要: 全站HTTPS時代的到來,這也是最近越來越多的網站上HTTPS和更換證書的原因。那麽究竟什麽是HTTPS?它為什麽會提升安全系數?CDN HTTPS又將如何做到安全性與性能同時提升?作為用戶,

    補習系列(9)-springboot 定時器用對

    empty cront apps 任務並發 轉發 gis execute 大小 定義 目錄 簡介 一、應用啟動任務 二、JDK 自帶調度線程池 三、@Scheduled 定制 @Scheduled 線程池 四、@Async 定制 @Async 線程池 小結 簡介 大

    學習程式設計的25個“坑”踩到

    0、忽視了程式設計終究是以人為本的。是的,機器的確會執行你的程式碼,但程式設計是為人們解決問題的,將他們的需求轉換為由其他人(或你自己線下)讀取,維護和修改的程式碼。 1、未能花充足的時間練習程式設計。 根據工作或日程安排,你可能會花費大量時間在與程式設計相關的任務上,但實際上這些並非程式設計本

    深挖價值讓資料“說話”準備好

    隨著AI技術的深入發展,近幾年來與企業級資料相關的討論層出不窮。 如何儲存?怎樣呼叫?呼叫的時候又該如何確保隱私不被洩露? …… 儘管資料專家一波接著一波,但針對企業如何理解、儲存、使用資料,並通過其實現更大商業價值的探索從未改變。 對此,百度雲早就get到了開發者們的資料痛點。