1. 山脈數組的峰頂索引(852)
題目描述:
算法原理:
根據題意我們可以將數組分為兩個部分,一個部分是arr[mid-1]<arr[mid],另一個部分為arr[mid-1]>arr[mid],此時不難發現我們可以將二分查找循環內的條件設置為上述條件,雖然此時會出現mid-1越界的問題,但是完全不用擔心,因為left和right下標分別從1和arr.length-2開始的,題目的意思就是山峰是不會出現在0和arr.length-1這兩個位置的,所以可以直接跳過。
代碼如下:
class Solution {public int peakIndexInMountainArray(int[] arr) {int left = 1, right = arr.length - 2;while (left < right) {int mid = left + (right - left + 1) / 2;if (arr[mid] > arr[mid - 1]) {left = mid;} else {right = mid - 1;}}return left;}
}
題目鏈接
2. 尋找峰值(162)
題目描述:
算法原理:
這一題和第二題是類似的,唯一的不同點在于這一題的峰值可能不為一并且-1下標以及nums.length下標都是假設為負無窮,所以我們的right以及left指針要分別從nums.length-1以及0開始。
這里具有的二段性和上題一致,當arr[mid]>arr[mid-1]時,mid到nums.length-1的區間必有峰,所以left要提到mid的位置,當arr[mid]<arr[mid-1]時,0到mid-1區間內必然有峰,所以right提到mid-1,畫圖還是比較好理解的。
因為mid必然是大于0的,所以不用去擔心越界問題,以及為了防止死循環要給mid計算加一。
代碼如下:
class Solution {public int peakIndexInMountainArray(int[] arr) {int left = 1, right = arr.length - 2;while (left < right) {int mid = left + (right - left + 1) / 2;if (arr[mid] >arr[mid - 1]) {left = mid;} else {right = mid - 1;}}return left;}
}
題目鏈接
3. 尋找旋轉排序數組中的最小值(153)
題目描述:
算法原理:
其實使用二分算法做這類題如果知道并且理解了上一篇博客中的模板的話,剩下來就是分析題目中的二段性,分析完之后直接套模板即可。那么這題的二段性一張圖足以描述,如下。
這張圖是數組的一種抽象表示,此時y軸就是nums數組的值,x軸就是nums數組的下標,每個旋轉后的數組元素大小起伏都是這樣的,不難發現對于nums數組的最后一個元素,nums數組的前半部分是嚴格大于它的,但是nums數組的后半部分都是嚴格小于它的,由此我們就發現了nums數組的二段性,可以以nums數組的最后一個元素作為基準,具體邏輯如代碼所示。
代碼如下:
class Solution {public int findMin(int[] nums) {int n = nums.length - 1;int left = 0, right = n;while (right > left) {int mid = left + (right - left) / 2;if (nums[mid] > nums[n]) {left = mid + 1;} else {right = mid;}}return nums[right];}
}
題目鏈接
4. 點名(LCR 173)
題目描述:
算法原理:
使用二分查找的方法來解決,主要就是要去找到數組中的二段性。根據題目不難發現其中的records數組在沒有同學缺席之前,records[i]都是等于i的,在有同學缺席之后records[i]就等于i+1了,這就是數組二段性的體現。還要注意一個細節就是如果數組中缺失的是最后一個數時需要返回數組長度加一。
代碼如下:
class Solution {public int takeAttendance(int[] records) {int left = 0, right = records.length - 1;while (left < right) {int mid = left + (right - left) / 2;if (records[mid] - mid == 0) {left = mid + 1;} else {right = mid;}}return records[right] == right ? records.length : right;}
}
題目鏈接