Merge 71c99f9180c298164c52bd731a5d5c83c311b741 into 7de885099a36678d7d458e45d24d07a1a68b6ca3

This commit is contained in:
luocaodan 2018-08-09 14:28:39 +00:00 committed by GitHub
commit a89b8c992b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -633,36 +633,26 @@ public int RectCover(int n) {
## 解题思路 ## 解题思路
当 nums[m] <= nums[h] 的情况下,说明解在 [l, m] 之间,此时令 h = m否则解在 [m + 1, h] 之间,令 l = m + 1。 先取出数组的第一个元素用于缩小区间二分查找中如果array[mid] > array[mid + 1]那么array[mid + 1]就是最小值直接返回如果不符合条件判断array[mid]和数组的第一个元素若大于数组的第一个元素说明这时在旋转数组的左边应该继续在右边区间查找反之在左边区间查找如果array[mid] > array[mid + 1] 永远不满足,说明数据所有元素都相等,直接返回第一个元素
因为 h 的赋值表达式为 h = m因此循环体的循环条件应该为 l < h详细解释请见 [Leetcode 题解](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3.md#%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE) 二分查找部分 复杂度O(logN)
但是如果出现 nums[l] == nums[m] == nums[h],那么此时无法确定解在哪个区间,因此需要切换到顺序查找。
复杂度O(logN) + O(1)
```java ```java
public int minNumberInRotateArray(int[] nums) { public int minNumberInRotateArray(int [] array) {
if (nums.length == 0) if (array.length == 0)
return 0; return 0;
int l = 0, h = nums.length - 1; int v = array[0];
while (l < h) { int lo = 0, hi = array.length - 1;
int m = l + (h - l) / 2; while (lo <= hi) {
if (nums[l] == nums[m] && nums[m] == nums[h]) int mid = lo + ((hi-lo)>>>1);
return minNumber(nums, l, h); if (mid+1 < array.length && array[mid] > array[mid+1])
else if (nums[m] <= nums[h]) return array[mid + 1];
h = m; if (array[mid] >= v)
lo = mid + 1;
else else
l = m + 1; hi = mid - 1;
} }
return nums[l]; return array[0];
}
private int minNumber(int[] nums, int l, int h) {
for (int i = l; i < h; i++)
if (nums[i] > nums[i + 1])
return nums[i + 1];
return nums[l];
} }
``` ```