二分查找

在有序表中,取中间记录为比较对象,若给定值与中间记录的关键字相等,则查找成功,若给定值小于中间记录的关键字,则在中间记录的左半区继续查找,若给定值大于中间记录的关键字,则在右半区进行查找,不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。

  1. int Binary_Search(int *a,int n,int key)
  2. {
  3. int low,high,mid;
  4. low = 1; #定义最低下标记录为记录首位
  5. high = n; #定义最高下标为记录末位
  6. while low<=high
  7. {
  8. mid = low + high / 2;
  9. if(key<a[mid])
  10. high = mid - 1;
  11. else if (key > a[mid])
  12. low = mid +1;
  13. else
  14. return mid;
  15. }
  16. return 0
  17. }
  18. 有序
  19. O(logn)

面试题 10.05. 稀疏数组搜索

  1. class Solution:
  2. def findString(self, words: List[str], s: str) -> int:
  3. left, right = 0, len(words) - 1
  4. while left <= right:
  5. mid = left + (right - left) // 2
  6. temp = mid # 记录一下mid的位置,因为下面要移动mid来寻找非空串,如果查找失败需要用temp来恢复位置
  7. while words[mid] == '' and mid < right: # 如果mid对应空串则向右寻找
  8. mid += 1
  9. if words[mid] == '':
  10. # 该情况发生在mid走到了right-1的位置,如果right仍对应空,则说明temp右侧都是空,所以将右边界进行改变
  11. right = temp - 1
  12. continue
  13. if words[mid] == s: # 该情况发生在mid在右移的过程中发现了非空串,则进行正常的二分查找
  14. return mid
  15. elif s < words[mid]:
  16. right = mid - 1
  17. else:
  18. left = mid + 1
  19. return -1

350. 两个数组的交集 II

  1. class Solution:
  2. def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
  3. nums1.sort()
  4. nums2.sort()
  5. r = []
  6. left,right =0,0
  7. while left < len(nums1) and right<len(nums2):
  8. if nums1[left] <nums2[right]:
  9. left += 1
  10. elif nums1[left] == nums2[right]:
  11. r.append(nums1[left])
  12. left +=1
  13. right += 1
  14. else:
  15. right +=1
  16. return r

74. 搜索二维矩阵

注意到输入的 m x n 矩阵可以视为长度为 m x n的有序数组。

查找 - 图1

由于该 虚 数组的序号可以由下式方便地转化为原矩阵中的行和列 (我们当然不会真的创建一个新数组) ,该有序数组非常适合二分查找。

row = idx // n , col = idx % n。

  1. class Solution:
  2. def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
  3. m = len(matrix) #行
  4. if m == 0:
  5. return False
  6. n = len(matrix[0]) #列
  7. left,right = 0,m*n-1
  8. while left <= right:
  9. pivot_idx = (left + right) // 2
  10. row = pivot_idx // n
  11. col = pivot_idx % n
  12. pivot_elenmnt = matrix[row][col]
  13. if pivot_elenmnt < target:
  14. left = pivot_idx + 1
  15. elif pivot_elenmnt > target:
  16. right = pivot_idx -1
  17. else:
  18. return True
  19. return False