Leetcode 二分題目總結

2021-09-25 05:55:37 字數 4349 閱讀 4675

二分搜尋一般有列舉下標和列舉值兩種,mid表示下標或者某乙個值。

這樣的二分搜所通常涉及兩個函式定義,乙個叫upper_bound, 乙個叫lower_bound,這裡會產生邊界問題。

從筆試/面試的角度來說, 筆試中,常常涉及到二分搜尋的題目,這樣的題目,由於時間充足,允許不斷除錯,有部分分,另外需要注意,筆試中往往不會給出出錯資料,需要自己想辦法除錯,所以這類題目往往是必須要拿下的。

在國內面試中,往往不會涉及過於難的二分題目,因為除非背下模板,否則需要手動除錯處理邊界問題。這在有限的面試時間中是不現實的,特別是手寫**。所以一般只要實現比較簡單的二分搜尋即可。

leetcode 69 sqrt(x)

實現 int sqrt(int x) 函式。

計算並返回 x 的平方根,其中 x 是非負整數。

由於返回型別是整數,結果只保留整數的部分,小數部分將被捨去。

這道題目一般使用二分搜尋或者牛頓迭代,因為牛頓迭代涉及到公式的推導,面試中一般不會出現,所以一般就是用二分的方法做。

根據這裡的思路,就是找臨界點,臨界點右邊的數n*n>x, 臨界點左邊<=x,整數二分通常會涉及到臨界點的處理問題,這裡一種方法是背標準的模板,另一種方法是用乙個標準的左閉右閉模板,然後自己除錯。這裡注意處理溢位問題。

class solution 

left, right := 0, len(matrix)*len(matrix[0])-1

for left<=right

if val > target else

}return false

}

leetcode 278. 第乙個錯誤的版本

是產品經理,目前正在帶領乙個團隊開發新的產品。不幸的是,你的產品的最新版本沒有通過質量檢測。由於每個版本都是基於之前的版本開發的,所以錯誤的版本之後的所有版本都是錯的。

假設你有 n 個版本 [1, 2, ..., n],你想找出導致之後所有版本出錯的第乙個錯誤的版本。

你可以通過呼叫 bool isbadversion(version) 介面來判斷版本號 version 是否在單元測試**錯。實現乙個函式來查詢第乙個錯誤的版本。你應該儘量減少對呼叫 api 的次數。

示例:

給定 n = 5,並且 version = 4 是第乙個錯誤的版本。

呼叫 isbadversion(3) -> false

呼叫 isbadversion(5) -> true

呼叫 isbadversion(4) -> true

所以,4 是第乙個錯誤的版本。

這道題目是比較簡單的,找乙個臨界點,左邊是好的,右邊是壞的。

public class solution extends versioncontrol 

return left;

}}

leetcode 153. 尋找旋轉排序陣列中的最小值

假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。

( 例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。

請找出其中最小的元素。

你可以假設陣列中不存在重複元素。

示例 1:

輸入: [3,4,5,1,2]

輸出: 1

示例 2:

輸入: [4,5,6,7,0,1,2]

輸出: 0

找到乙個臨界點,臨界點右邊的數小於第乙個數,臨界點左邊的數大於第乙個數

func findmin(nums int) int 

for left<=right

var left int

var right int

if target==nums[end]else if targettargetelse

}return -1

}func findmin(nums int) int

for left<=rightelse if target>nums[mid]else

}if target<=nums[left]

return left+1;

}

leetcode 34. 在排序陣列中查詢元素的第乙個和最後乙個位置

這道題目就是upper_bound 和lower_bound的函式,涉及到很多邊界處理問題

func searchrange(nums int, target int) int 

}nlen := len(nums)

left, right := 0, nlen-1

var start, end int; // 答案

for right>=leftelse

}if nums[left]!=target;

}start = left;

left, right = 0, nlen-1

for right>=leftelse

}return left

}func check(nums int, left int, mid int) bool

}return count>mid-left+1

}

leetcode 275. h指數 ii

給定一位研究者**被引用次數的陣列(被引用次數是非負整數),陣列已經按照公升序排列。編寫乙個方法,計算出研究者的 h 指數。

h 指數的定義: 「h 代表「高引用次數」(high citations),一名科研人員的 h 指數是指他(她)的 (n 篇**中)至多有 h 篇**分別被引用了至少 h 次。(其餘的 n - h 篇**每篇被引用次數不多於 h 次。)"

示例:

輸入: citations = [0,1,3,5,6]

輸出: 3 

解釋: 給定陣列表示研究者總共有 5 篇**,每篇**相應的被引用了 0, 1, 3, 5, 6 次。

由於研究者有 3 篇**每篇至少被引用了 3 次,其餘兩篇**每篇被引用不多於 3 次,所以她的 h 指數是 3。

這道題是有一定難度的,首先如果直接列舉h指數,那麼就要遍歷一遍陣列,時間複雜度至少是o(nlogn),事實上,這到題目有o(logn) 的做法,因為h的含義和**篇數/下標有關,所以列舉的是下標,這裡更新的條件有些難想。同時,不難按照通常那樣返回left或right,而要用乙個變數記錄滿足要求的res

func hindex(citations int) int 

left, right :=0, n-1

for left<=rightelse

}return res

}

leetcode 162. 尋找峰值

峰值元素是指其值大於左右相鄰值的元素。

給定乙個輸入陣列 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素並返回其索引。

陣列可能包含多個峰值,在這種情況下,返回任何乙個峰值所在位置即可。

你可以假設 nums[-1] = nums[n] = -∞。

示例 1:

輸入: nums = [1,2,3,1]

輸出: 2

解釋: 3 是峰值元素,你的函式應該返回其索引 2。

示例 2:

輸入: nums = [1,2,1,3,5,6,4]

輸出: 1 或 5 

解釋: 你的函式可以返回索引 1,其峰值元素為 2;

或者返回索引 5, 其峰值元素為 6。

說明:你的解法應該是 o(logn) 時間複雜度的。

這道題目是比較難得,   優化結論是,如果nums[mid]nums[mid]如果 nums[mid]>nums[mid-1] && nums[mid]>nums[mid+1] 那麼mid是峰值。

由於這裡涉及到mid-1和mid+1,會出現大量得邊界問題需要解決,注意看程式得**

所以處理方法是下面這樣

func findpeakelement(nums int) int 

for left<=rightelse if mid ==n-1|| nums[mid]>nums[mid+1]else

}else if mid+1nums[mid-1]else}}

return left

}

二分查詢題目總結

一位大佬曾經說過 二分查詢思路很簡單,細節是魔鬼 做了一些題後感慨真的是這樣 二分查詢法 實質就是將乙個有序的資料集不斷地對半分割,直至找到目標值 其中兩個最關鍵的也是在面對不同題目會稍有不同的就是怎麼退出迴圈,怎麼縮小查詢空間。怎麼突破這兩點就是關鍵 在乙個有序資料集裡查詢乙個乙個目標數可以有一下...

LeetCode二分查詢總結

對3道二分查詢題的總結,於 soulmachine,code ganker search insert position search in rotated sorted array search in rotated sorted array ii 1.最基本的二分查詢 思路就是每次取中間,如果等...

leetcode經典題目(3) 二分查詢

二分查詢的注意點 1 左右指標的初始值以及更新規則 2 迴圈條件,l h得到的h比l小1,l1.求平方根 no.69 題目描述 計算並返回 x 的平方根,其中 x 是非負整數。由於返回型別是整數,結果只保留整數的部分,小數部分將被捨去。解題思路 二分查詢。在迴圈條件為 l h 並且迴圈退出時,h 總...