哈哈,剑指offer第11题跟leetcode154题相同。题友把一个刷成简单,一个刷成困难,挺清奇的。
分析:
- 非重复例子 34512 ,不管pivot在哪,都有一段严格递增的区间。
- 有重复值的时候pivot和最小值点的关系不确定 222312,pivot索引是3,判断出来严格递增关系,此刻最小值在5位置上
23122222,如果此时pivot索引是4,最小值在3位置上。
我的代码:
考虑pivot和最左侧元素的大小。
public static void main(String[] args) {
int [] arr = {2,2,2,3,1,2};
int minIndex = process(arr);
System.out.println(minIndex);
}
public static int process(int[] arr ){
int min = Integer.MAX_VALUE;
int l = 0;
int r= arr.length-1;
while(l <= r){
int mid = l + ((r-l)>>1);
if(arr[mid] > arr[l]){
min = Math.min(min, arr[l]);
l = mid+1;
}else if(arr[mid] < arr[l]){
min = Math.min(min, arr[mid]);
r = mid-1;
}else {
min = Math.min(min, arr[mid]);
l = l+1;
}
}
return min;
}
官方题解:
对三种情况的讨论,其中low是每一步二分区域的左边界,hight是右边界
1、
2、
3、这个图画的不太通用,图中第一个pivot后面也可能出现大于pivot的情况,比如我的例子
2222312,第一次的pivot索引是3。
代码上的区别,
- 他是选用的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) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 ```