【LeetCode/LintCode】 題解丨大廠演算法面試模板:二分查詢
阿新 • • 發佈:2020-09-18
給定一個排序的整數陣列(升序)和一個要查詢的整數target,用O(logn)的時間查詢到target第一次出現的下標(從0開始),如果target不存在於陣列中,返回-1。
線上評測地址:
樣例 1:
輸入:[1,4,4,5,7,7,8,9,9,10],1
輸出: 0
樣例解釋:
第一次出現在第0個位置。
樣例 2:
輸入: [1, 2, 3, 3, 4, 5, 10],3
輸出: 2
樣例解釋:
第一次出現在第2個位置
樣例 3:
輸入: [1, 2, 3, 3, 4, 5, 10],6 輸出: -1 樣例解釋: 沒有出現過6, 返回-1
解題思路
題目提到,給定的陣列已經排序,若從小到大遍歷陣列查詢target,則時間複雜度為O(n)O(n),n為陣列長度。需要用一個O(logn)O(logn)的時間複雜度去完成本題,那麼需要用到二分查詢。
二分查詢常用於查詢有序陣列中目標數target的位置,用left和right記錄target所在的區間端點,每次將區間的中間位置值和target作比較,然後移動區間端點。
演算法流程
- 將區間賦值為整個陣列區間(left = 0, right = n - 1),取中間位置mid
- 若a[mid] < target,則將區間縮小到原區間的右區間(left = mid + 1)
- 若a[mid] >= target,則將區間縮小至原區間的左區間(right = mid)
- 若left >= right 時,若a[right] = target則返回right, 否則返回-1
複雜度分析
- 時間複雜度:O(logn)
- 每次查詢都將區間縮小至原來長度的一半,可見查詢的最多次數為logn
- 空間複雜度:O(1)
- 查詢不需要開闢新的非常數級空間,只需在原陣列基礎上進行查詢即可
程式碼
public class Solution { /** * @param nums: The integer array. * @param target: Target to find. * @return: The first position of target. Position starts from 0. */ public int binarySearch(int[] nums, int target) { int left = 0; int right = nums.length - 1; int mid; while (left < right) { //得到中間位置 mid = (right + left) / 2; if (nums[mid] < target) { left = mid + 1; } else { right = mid; } } if (nums[right] == target) { return right; } return -1; } }
更多題解參考: