二分(Binary Search) 总结
一、模板: 用start/end 双指针逼近: while(start + 1 < end): 可以避免find last position of target 等问题 case : [1,1] 造成的死循环
如果target不存在,循环结束后,start 和 end 会夹住应该插入target的位置。
1. 如果有重复的target, 会找到最前面的那个:
1 int start = 0, end = arr.length - 1; 2 while(start + 1 < end){ 3 int mid = start + (end - start) / 2; 4 if(arr[mid] < x){ 5 start = mid; 6 } 7 else{ 8 end = mid; 9 } 10 }
2.如果有重复target,找到最后面那个:
1 int start = 0, end = arr.length - 1; 2 while(start + 1 < end){ 3 int mid = start + (end - start) / 2; 4 if(arr[mid] <= x){ 5 start = mid; 6 } 7 else{ 8 end = mid; 9 } 10 }
3. 跳出循环时指针位置对比: √: target Ο: 小于target,Δ: 大于target
往前找 往后找
ΟΟΟ√ΔΔΔ ΟΟΟ√ΔΔΔ
↑↑ ↑↑
ΟΟΟΔΔΔ ΟΟΟΔΔΔ
↑↑ ↑↑
ΟΟΟ√√√ΔΔΔ ΟΟΟ√√√ΔΔΔ
↑↑ ↑↑
ΟΔΔΔ ΟΔΔΔ
↑↑ ↑↑
ΟΟΟΔ ΟΟΟΔ
↑↑ ↑↑
二、应用
将所有二分都抽象为 O...OOXX...X 模型:
再根据具体题意来确定具体是找最后一个O, 还是找第一个X。
最后一个O:“往前找”
第一个X : “往后找”
1. Find Minimum/ Maximum in Rotated Sorted Array:
pivot选择最重要:
升序 找最小(找图里的1): 第一个X
选nums[nums.length - 1] ——> 这样才能找的到没rotate过的升序数组的最小值
升序 找最大 (找图里的6): 最后一个O
pivot nums[0] : 同理
2. 二分答案
3. Rotated Array
a. no duplicates:
先判断mid左边还是右边, 然后在判断target,在mid左边还是右边。 pivot选择nums[end]
b. duplicates:
这时 nums[mid] = pivot 的时候 并不能判断target在那边 [1,1,3,1] 和 [3,1,1], 所以只能将pivot左移一位, worst case: O(N)

浙公网安备 33010602011771号