码迷,mamicode.com
首页 > 编程语言 > 详细

剑指offer:旋转数组的最小数字

时间:2017-12-30 22:34:49      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:bottom   剑指offer   radius   开始   ber   content   sim   round   blog   

题目描述

一个递增排序的数组的一个旋转(把一个数组最开始的若干元素搬到数组的末尾,称之为数组的旋转),输出旋转数组的最小元素。

解题思路:

旋转之后的数组实际上可以划分成两个有序的子数组:前面子数组的大小都大于后面子数组中的元素 
注意到实际上最小的元素就是两个子数组的分界线。本题目给出的数组一定程度上是排序的,因此我们试着用二分查找法寻找这个最小的元素。 
  
(1)我们用两个指针left,right分别指向数组的第一个元素和最后一个元素。按照题目的旋转的规则,第一个元素应该是大于最后一个元素的(没有重复的元素)。 
但是如果不是旋转,第一个元素肯定小于最后一个元素。 
  
(2)找到数组的中间元素。 
中间元素大于第一个元素,则中间元素位于前面的递增子数组,此时最小元素位于中间元素的后面。我们可以让第一个指针left指向中间元素。 
移动之后,第一个指针仍然位于前面的递增数组中。 
中间元素小于第一个元素,则中间元素位于后面的递增子数组,此时最小元素位于中间元素的前面。我们可以让第二个指针right指向中间元素。 
移动之后,第二个指针仍然位于后面的递增数组中。 
这样可以缩小寻找的范围。 
  
(3)按照以上思路,第一个指针left总是指向前面递增数组的元素,第二个指针right总是指向后面递增的数组元素。 

特殊情况考虑:旋转0个元素、三个指针相等情况(10111, 11101)

//
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
// 判断特殊情况
if (array==null||array.length==0)
return 0;
int firstIndex = 0;
int lastIndex = array.length - 1;
// 这里初始化mid为0的原因是,如果旋转0个元素那么最小值就是第一个元素
int midIndex = 0;
// 如果旋转0个元素则直接跳出循环
while (array[firstIndex] >= array[lastIndex]){
if (firstIndex+1==lastIndex){
midIndex = lastIndex;
break;
}
// 三指针相等时,只能顺序查找,这种情况非常容易漏,要非常细心
if (firstIndex==lastIndex && firstIndex==midIndex){
return MinInOrder(array, firstIndex, lastIndex);
}
midIndex = (firstIndex + lastIndex) / 2;
if (array[firstIndex] <= array[midIndex]){
firstIndex = midIndex;
}
else{
lastIndex = midIndex;
}
}
return array[midIndex];
}
public int MinInOrder(int [] array, int low, int high){
int ret = array[low];
for (int i=low+1; i<high; i++){
if (array[i] < ret){
ret = array[i];
}
}
return ret;
}
}

剑指offer:旋转数组的最小数字

标签:bottom   剑指offer   radius   开始   ber   content   sim   round   blog   

原文地址:https://www.cnblogs.com/LiCheng-/p/8151107.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!