二分(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) 

posted on 2019-05-30 08:15  OldJimmy  阅读(230)  评论(0)    收藏  举报

导航