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

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

问题描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

思路分析

1.先判断数组是否为空,数组的元素是否大于零。
2.观察会发现旋转数组是由两个递增数组组成。{3,4,5,} {1,2}
3.举例说明一般的情况。

 如:数组{3,4,5,1,2},两个指针,p1指向首元素,p2指向尾元素,p指向p1和p2的中间元素。
   
    3    4    5    1    2
    p1        p         p2
 
   将p和p1指向元素进行比较,(先和左边比较)
   5>3,说明5位于第一个递增子数组,并且最小的数一定在它后面。
   所以将p1移动到p的位置。
   
   3    4    5     1     2
             p1    p     p2
             
   此时的p,为更新后的p1和p2的中间元素。
   将p和p2指向元素进行比较,(再和右边比较)
   1<2,说明1位于第二个递增子数组,并且最小的数一定在它前面或者自己就是最小的数字。
   所以将p2移动到p的位置。
   
   3    4    5     1     2
             p1    p2   
             
   此时,p1和p2相邻,则p2为最小的数字

4.举例说明特殊的情况。

 如:数组{2,1,2,2,2},{2,2,2,1,2} 均为{1,2,2,2,2}的旋转
   
    2    1    2    2    2                      2    2    2    1    2
    p1        p         p2                     p1        p         p2
 
   可以看出两个数组都是 p1=p=p2
   因此无法判断,p位置元素出于第一个递增数列还是第二个。
   上面左边情况中,p属于第二个子数组。上面右边情况中,p属于第一个子数组。
   此时,采取顺序查找的方法,按着顺序依次判断。

代码

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array == null || array.length <= 0){
            return -1;
        }
        int index1=0;
        int index2=array.length-1;
        int indexMid=index1;//此处把indexMid的值初始为index1是因为如果旋转的是0个元素,
        // 则数组等于本身,则第一个元素就是要找的最小元素。
        while(array[index1]>=array[index2]){
            //两个指针相邻的情况
            if(index2-index1==1){
                indexMid=index2;
                break;
            }

            indexMid=(index1+index2)/2;
            //和左边比较
            if(array[index1]<=array[indexMid]){
                index1=indexMid;
            }
            //和右边比较
            else if(array[index2]>=array[indexMid]){
                index2=indexMid;
            }

            //特殊情况
            if(array[index1]==array[index2]&&array[index1]==array[indexMid]){
                return MinInOrder(array,index1,index2);
            }
        }
        return array[indexMid];
    }
    private int MinInOrder(int array[],int index1,int index2) {
        int result = array[index1];
        for (int i = index1+1; i <= index2; i++) {
            if (result > array[i]) {
                result = array[i];
            }
        }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值