@@ -78,6 +78,26 @@ class Solution:
7878 return - 1
7979```
8080
81+ ``` Python
82+ class Solution :
83+ def search (self , nums : List[int ], target : int ) -> int :
84+ if not nums:
85+ return - 1
86+ start = 0
87+ end = len (nums) - 1
88+ while start + 1 < end:
89+ mid = (start + end) // 2
90+ if nums[mid] < target:
91+ start = mid
92+ else :
93+ end = mid
94+ if nums[start] == target:
95+ return start
96+ if nums[end] == target:
97+ return end
98+ return - 1
99+ ```
100+
81101## 常见题目
82102
83103### [ find-first-and-last-position-of-element-in-sorted-array] ( https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/ )
@@ -158,6 +178,41 @@ class Solution:
158178 return Range
159179```
160180
181+ ``` Python
182+ class Solution :
183+ def searchRange (self , nums : List[int ], target : int ) -> List[int ]:
184+ result = [- 1 , - 1 ]
185+ if not nums:
186+ return result
187+ start = 0
188+ end = len (nums) - 1
189+ while start + 1 < end:
190+ mid = (start + end) // 2
191+ if nums[mid] < target:
192+ start = mid
193+ else :
194+ end = mid
195+ if nums[start] == target:
196+ result[0 ] = start
197+ elif nums[end] == target:
198+ result[0 ] = end
199+ else :
200+ return result
201+ start = 0
202+ end = len (nums) - 1
203+ while start + 1 < end:
204+ mid = (start + end) // 2
205+ if nums[mid] <= target:
206+ start = mid
207+ else :
208+ end = mid
209+ if nums[start] == target:
210+ result[1 ] = start
211+ if nums[end] == target:
212+ result[1 ] = end
213+ return result
214+ ```
215+
161216### [ search-insert-position] ( https://leetcode-cn.com/problems/search-insert-position/ )
162217
163218> 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
@@ -182,6 +237,28 @@ class Solution:
182237 return l
183238```
184239
240+ ``` Python
241+ class Solution :
242+ def searchInsert (self , nums : List[int ], target : int ) -> int :
243+ if not nums:
244+ return 0
245+ start = 0
246+ end = len (nums) - 1
247+ while start + 1 < end:
248+ mid = (start + end) // 2
249+ if nums[mid] < target:
250+ start = mid
251+ else :
252+ end = mid
253+ if target <= nums[start]:
254+ return start
255+ if target <= nums[end]:
256+ return end
257+ if target > nums[end]:
258+ return end + 1
259+ return 0
260+ ```
261+
185262### [ search-a-2d-matrix] ( https://leetcode-cn.com/problems/search-a-2d-matrix/ )
186263
187264> 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
@@ -224,6 +301,32 @@ class Solution:
224301 return False
225302```
226303
304+ ``` Python
305+ class Solution :
306+ def searchMatrix (self , matrix : List[List[int ]], target : int ) -> bool :
307+ l, r = 0 , len (matrix) - 1
308+ while l <= r:
309+ mid = l + (r - l) // 2
310+ if matrix[mid][0 ] == target:
311+ return True
312+ elif matrix[mid][0 ] < target:
313+ l = mid + 1
314+ else :
315+ r = mid - 1
316+ row = r
317+ l, r = 0 , len (matrix[0 ]) - 1
318+ while l <= r:
319+ mid = l + (r - l) // 2
320+ if matrix[row][mid] == target:
321+ return True
322+ elif matrix[row][mid] < target:
323+ l = mid + 1
324+ else :
325+ r = mid - 1
326+
327+ return False
328+ ```
329+
227330### [ find-minimum-in-rotated-sorted-array] ( https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/ )
228331
229332> 假设按照升序排序的数组在预先未知的某个点上进行了旋转,例如,数组 [ 0, 1, 2, 4, 5, 6, 7] 可能变为 [ 4, 5, 6, 7, 0, 1, 2] 。请找出其中最小的元素。假设数组中无重复元素。
@@ -246,6 +349,23 @@ class Solution:
246349 return nums[l]
247350```
248351
352+ ``` Python
353+ class Solution :
354+ def findMin (self , nums : List[int ]) -> int :
355+ start = 0
356+ end = len (nums) - 1
357+ while start + 1 < end:
358+ mid = (start + end) // 2
359+ if nums[end] < nums[mid]:
360+ start = mid
361+ else :
362+ end = mid
363+ if nums[start] < nums[end]:
364+ return nums[start]
365+ else :
366+ return nums[end]
367+ ```
368+
249369### [ find-minimum-in-rotated-sorted-array-ii] ( https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/ )
250370
251371> 假设按照升序排序的数组在预先未知的某个点上进行了旋转,例如,数组 [ 0, 1, 2, 4, 5, 6, 7] 可能变为 [ 4, 5, 6, 7, 0, 1, 2] 。请找出其中最小的元素。数组中可能包含重复元素。
@@ -268,6 +388,27 @@ class Solution:
268388 return nums[l]
269389```
270390
391+ ``` Python
392+ class Solution :
393+ def findMin (self , nums : List[int ]) -> int :
394+ start = 0
395+ end = len (nums) - 1
396+ while start + 1 < end:
397+ while start < end and nums[end] == nums[end- 1 ]:
398+ end -= 1
399+ while start < end and nums[start] == nums[start+ 1 ]:
400+ start += 1
401+ mid = (start + end) // 2
402+ if nums[mid] >= nums[end]:
403+ start = mid
404+ else :
405+ end = mid
406+ if nums[start] < nums[end]:
407+ return nums[start]
408+ else :
409+ return nums[end]
410+ ```
411+
271412### [ search-in-rotated-sorted-array] ( https://leetcode-cn.com/problems/search-in-rotated-sorted-array/ )
272413
273414> 假设按照升序排序的数组在预先未知的某个点上进行了旋转,例如,数组 [ 0, 1, 2, 4, 5, 6, 7] 可能变为 [ 4, 5, 6, 7, 0, 1, 2] 。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1。假设数组中不存在重复的元素。
@@ -295,6 +436,30 @@ class Solution:
295436 return - 1
296437```
297438
439+ ``` Python
440+ class Solution :
441+ def search (self , nums : List[int ], target : int ) -> int :
442+ start = 0
443+ end = len (nums) - 1
444+ while start + 1 < end:
445+ mid = (start + end) // 2
446+ if nums[start] < nums[mid]:
447+ if nums[start] <= target <= nums[mid]:
448+ end = mid
449+ else :
450+ start = mid
451+ else :
452+ if nums[mid] <= target <= nums[end]:
453+ start = mid
454+ else :
455+ end = mid
456+ if nums[start] == target:
457+ return start
458+ if nums[end] == target:
459+ return end
460+ return - 1
461+ ```
462+
298463### [ search-in-rotated-sorted-array-ii] ( https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/ )
299464
300465> 假设按照升序排序的数组在预先未知的某个点上进行了旋转,例如,数组 [ 0, 0, 1, 2, 2, 5, 6] 可能变为 [ 2, 5, 6, 0, 0, 1, 2] 。编写一个函数来判断给定的目标值是否存在于数组中,若存在返回 true,否则返回 false。数组中可能包含重复元素。
@@ -326,6 +491,37 @@ class Solution:
326491 return False
327492```
328493
494+ ``` Python
495+ class Solution :
496+ def search (self , nums : List[int ], target : int ) -> bool :
497+ start = 0
498+ end = len (nums) - 1
499+ while start + 1 < end:
500+ while start < end and nums[end] == nums[end- 1 ]:
501+ end -= 1
502+ while start < end and nums[start] == nums[start+ 1 ]:
503+ start += 1
504+ if end - start < 2 :
505+ break
506+ middle = (start+ end) // 2
507+ if target == nums[middle]:
508+ return True
509+ if nums[start] < nums[middle]:
510+ if nums[start] <= target < nums[middle]:
511+ end = middle
512+ else :
513+ start = middle
514+ else :
515+ if nums[middle] < target <= nums[end]:
516+ start = middle
517+ else :
518+ end = middle
519+ if nums[start] == target or nums[end] == target:
520+ return True
521+ else :
522+ return False
523+ ```
524+
329525## 隐含的二分搜索
330526
331527有时用到二分搜索的题目并不会直接给你一个有序数组,它隐含在题目中,需要你去发现或者构造。一类常见的隐含的二分搜索的问题是求某个有界数据的最值,以最小值为例,当数据比最小值大时都符合条件,比最小值小时都不符合条件,那么符合/不符合条件就构成了一种有序关系,再加上数据有界,我们就可以使用二分搜索来找数据的最小值。注意,数据的界一般也不会在题目中明确提示你,需要你自己去发现。
@@ -348,6 +544,23 @@ class Solution:
348544 return l
349545```
350546
547+ ``` Python
548+ class Solution :
549+ def minEatingSpeed (self , piles : List[int ], h : int ) -> int :
550+ start = 1
551+ end = max (piles)
552+ while start < end:
553+ mid = (start + end) // 2
554+ time = 0
555+ for p in piles:
556+ time += (p + mid - 1 ) // mid
557+ if time > h:
558+ start = mid + 1
559+ else :
560+ end = mid
561+ return start
562+ ```
563+
351564## 总结
352565
353566二分搜索核心四点要素(必背&理解)
0 commit comments