1. 有序數組中的單一元素(540)
題目描述:
算法原理:
二分查找解題關鍵就在于去找到數組的二段性,這里數組的二段性是從單個數字a開始出現然后分隔出來的,如果mid落入左半部分那么當mid為偶數時nums[mid+1]等于nums[mid],當mid為奇數時nums[mid]等于nums[mid-1],mid落入右半部分則相反。
細節:
循環內的判斷條件首先需要判斷mid是偶數還是奇數,接著還要判斷相等的關系,是比較麻煩的。我們發現規律當mid為偶數異或1時就會得到mid+1,當mid為奇數異或1時就會得到mid-1,因此我們的判斷條件直接簡化為nums[mid]是否等于nums[mid^1]。
代碼如下:
class Solution {public int singleNonDuplicate(int[] nums) {int left = 0, right = nums.length - 1;while (right > left) {int mid = left + (right - left) / 2;if (nums[mid] == nums[mid ^ 1]) {left = mid + 1;} else {right = mid;}}return nums[right];}
}
題目鏈接
2. 尋找旋轉排序數組中的最小值 II(154)
題目描述:
算法原理:
nums數組的二段性體現在nums[right],前半部分旋轉過去的值是大于等于nums[right]的,后半部分的值都是小于等于nums[right]。不過這題需要注意的地方就是因為數值是可以重復的,所以當nums[mid]等于nums[right]的時候我們是不知道mid是落在前半部分還是后半部分的,為了解決這種情況我們直接將right向左移動一位即可,移動之后因為我們求的是最小值,所以不會影響結果,并且達到了一種去重的效果。
代碼如下:
class Solution {public int findMin(int[] nums) {int left = 0, right = nums.length - 1;while (left < right) {int mid = left + (right - left) / 2;if (nums[mid] > nums[right]) {left = mid + 1;} else if (nums[mid] < nums[right]) {right = mid;} else {right -= 1;}}return nums[right];}
}
題目鏈接
3. 搜索二維矩陣(74)
題目描述:
算法原理:
這一題可以使用樸素二分查找的思想來解決,將多維數組看作一維的數組,此時鋪開來left=0、right=m*n-1,得到的mid位置的值在二維數組中可以表示為matrix[mid/n]matrix[mid%n],這里的m就是數組的維度數,n就是每個維度的元素個數。
代碼如下:
class Solution {public boolean searchMatrix(int[][] matrix, int target) {int m = matrix.length;int n = matrix[0].length;int left = 0, right = m * n - 1;while (left <= right) {int mid = left + (right - left) / 2;if (matrix[mid / n][mid % n] > target) {right = mid - 1;} else if (matrix[mid / n][mid % n] < target) {left = mid + 1;} else {return true;}}return false;}
}
題目鏈接