diff --git a/solutions/33. Search in Rotated Sorted Array.md b/solutions/33. Search in Rotated Sorted Array.md index 2bf1769..0137041 100644 --- a/solutions/33. Search in Rotated Sorted Array.md +++ b/solutions/33. Search in Rotated Sorted Array.md @@ -22,7 +22,7 @@ 所以拿nums[low]和nums[mid]比较不是一个好选择。再来看看nums[mid]和nums[high]比较: > * 若`nums[mid] < nums[high]`,此时最小值只能是位于[low, mid]。 -> * 否则若`nums[mid] > nums[high]`,此时最小值只能是位于[mid+1, low]。 +> * 否则若`nums[mid] > nums[high]`,此时最小值只能是位于[mid+1, high]。 > * 假设`nums[mid] == nums[high]`,此时`low = mid = high`,最小值就是nums[mid]。 可见用nums[mid]和nums[high]的大小关系可以确定最小值位于哪一个区间。 @@ -33,12 +33,13 @@ ## 思路二 思路一虽然时间复杂度为O(logn),但是却进行了两次查找,一点都不elegant,能不能直接一步到位呢?肯定还是二分法,那么我们应该如何判断target是在左半部分[low, mid)还是右半部分(mid, high]呢? -我们知道,判断一个数是否在一个有序数组数组是很方便的(只需要判断端点和这个数的大小关系),幸运的是,仔细分析此题的数组可知,左右两半至少有一半是有序的。所以我们可以判断target是否在这有序的一半,若在则丢弃掉另一半进入下一次循环,若不在则丢弃掉有序的这一半进入下一次循环。那么如何判断哪一半是有序的呢?也很简单,只需要判断左右端点即可,以左半部分为例: +我们知道,判断一个数是否在一个有序数组数组是很方便的(只需要判断端点和这个数的大小关系),幸运的是,仔细分析此题的数组可知,**左右两半至少有一半是有序的**。所以我们可以判断target是否在这有序的一半,若在则丢弃掉另一半进入下一次循环,若不在则丢弃掉有序的这一半进入下一次循环。那么如何判断哪一半是有序的呢?也很简单,只需要判断左右端点即可,以左半部分为例: * 若`nums[low] <= nums[mid]`,则左半部分一定是有序的(想想为什么); * 否则左半部分是无序的,则右半部分一定是有序的。 时间复杂度O(logn), 空间复杂度O(1) +> 注意此题不存在重复值,而[81. Search in Rotated Sorted Array II](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/)则可能有重复值。81题也是采用思路二,即先判断哪一半是有序的,但是当`nums[low] = nums[mid]`时无法判断哪一半有序,怎么办呢?很简单,那我们直接low++即可,即退化成顺序查找,所以81题最坏时间复杂度是O(n),此时数组中元素全相等且不等于target。 # C++ ## 思路一 @@ -98,4 +99,4 @@ public: return -1; } }; -``` \ No newline at end of file +```