面试题:旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。
思路:我们注意到旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都大于或者等于后面子数组的元素。我们还注意到最小的元素刚好是这两个子数组的分界线。在排序的数组中没我们可以用二分法实现O(logn)的查找。我们用两个指针分别指向数组的第一个元素和最后一个元素,按照旋转规则,第一个元素大于或者等于最后一个元素。
接着我们可以找到数组中间的元素。如果该中间元素位于前面的递增子数组,那么它应该大于或者等于第一个指针指向的元素。此时数组中最小的元素位于该之间元素的后面。我们可以把第一个指针指向该之间元素,这样就可以缩小寻找范围,移动之后的第一个指针仍然位于前面的递增数组。
同样,如果该中间元素位于后面的递增子数组,那么它应该小于或者等于第二个指针指向的元素。此时数组中最小的元素位于该之间元素的前面。我们可以把第二个指针指向该之间元素,这样就可以缩小寻找范围,移动之后的第二个指针仍然位于前面的递增数组。
对于特殊情况,如下面的情况,就需要利用顺序查找。对于数组{0,1,1,1,1}的旋转。
| 1 | 0 | 1 | 1 | 1 |
|---|---|---|---|---|
| p1 | Mid | p2 |
| 1 | 1 | 1 | 0 | 1 |
|---|---|---|---|---|
| p1 | Mid | p2 |
|
|
|
|
|
|
|
|