哈哈,剑指offer第11题跟leetcode154题相同。题友把一个刷成简单,一个刷成困难,挺清奇的。
    image.pngimage.png
    分析:

    • 非重复例子 34512 ,不管pivot在哪,都有一段严格递增的区间。
    • 有重复值的时候pivot和最小值点的关系不确定 222312,pivot索引是3,判断出来严格递增关系,此刻最小值在5位置上

    23122222,如果此时pivot索引是4,最小值在3位置上。
    我的代码:
    考虑pivot和最左侧元素的大小。

    1. public static void main(String[] args) {
    2. int [] arr = {2,2,2,3,1,2};
    3. int minIndex = process(arr);
    4. System.out.println(minIndex);
    5. }
    6. public static int process(int[] arr ){
    7. int min = Integer.MAX_VALUE;
    8. int l = 0;
    9. int r= arr.length-1;
    10. while(l <= r){
    11. int mid = l + ((r-l)>>1);
    12. if(arr[mid] > arr[l]){
    13. min = Math.min(min, arr[l]);
    14. l = mid+1;
    15. }else if(arr[mid] < arr[l]){
    16. min = Math.min(min, arr[mid]);
    17. r = mid-1;
    18. }else {
    19. min = Math.min(min, arr[mid]);
    20. l = l+1;
    21. }
    22. }
    23. return min;
    24. }

    官方题解:
    对三种情况的讨论,其中low是每一步二分区域的左边界,hight是右边界
    1、
    image.png
    2、
    image.png
    3、这个图画的不太通用,图中第一个pivot后面也可能出现大于pivot的情况,比如我的例子
    2222312,第一次的pivot索引是3。
    image.png
    代码上的区别,

    • 他是选用的high位置进行比较,
    • 边界的处理,使得代码更加简洁,比如当pivot位置数字小于hight位置的时候,pivot也在下一次二分区间中。但是注意,往往边界的处理是跟二分pivot的选择方式紧密联系,这里pivot是用比较通用的方式(考虑越界)low+((high-low)>>1)的方式。 ```java class Solution { public int minArray(int[] numbers) {
        int low = 0;
        int high = numbers.length - 1;
        while (low < high) {
            int pivot = low + (high - low) / 2;
            if (numbers[pivot] < numbers[high]) {
                high = pivot;
            } else if (numbers[pivot] > numbers[high]) {
                low = pivot + 1;
            } else {
                high -= 1;
            }
        }
        return numbers[low];
      
      } }

    作者:LeetCode-Solution 链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/solution/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-by-leetcode-s/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 ```