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

本文介绍了一种寻找旋转数组中最小值的方法,通过判断数组是否已排序来决定采用直接比较还是二分查找法。

旋转数组的最小数字
时间限制:3秒 空间限制:32768K 热度指数:269374
本题知识点: 查找

题目描述

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

思路讲解

题目已讲明输入的是一个非递减排序的数组的一个旋转,那么若数组的首元素小于数组的最后一个元素时该输入的数组一定是一串非递减排序的数组,那么最小值必然为该数组的首元素。若数组的首元素不小于数组的最后一个元素时该数组必然经历了旋转,此时便需要用二分法来解决问题。


代码实现

public class Solution {
	
    public static int minNumberInRotateArray(int [] array) {
    	
    	int len = array.length;
    	if (len == 0) {
    		return 0;
    	}
    	
    	int low = 0;
    	int high = len - 1;
    	int mid = (low + high)/2;
    	int min = array[low];
    	if (array[low] < array[high]) {     //说明已经是一个非递减数组
    		min = array[low];
    	}
    	
    	
    	//使用二分查找法   3 4 5 1 2 
    	while (array[low] >= array[high]) {
    
    		if (high - low == 1) {
    			return array[high];
    		}
    		
    		if (array[low] <= array[mid]) {    //说明数组 array[low] -> array[mid] 部分升序
    			low = mid;
    			mid = (mid + high)/2;
    		}
    		
    		if (array[low] > array[mid]) {    //说明数组 array[low] -> array[mid] 中出现旋转点
    			high = mid;
    			mid = (mid + low)/2;
    		}
    		
    		if (array[low] == array[mid] && array[mid] == array[high]) {   //当array[low] == array[mid] == array[high]时只能线性搜索
    			for (int i : array) {
					min = min < i ? min : i;
				}
    			
    			return min;
    		}
    	}
    	return min;
    }
    
    
    public static void main(String[] args) {
		
    	int[] array = new int[]{3,4,5,1,2};    
		
		int min = minNumberInRotateArray(array);
		System.out.println(min);
	}
}


编译结果




代码已传至github,阅读请至:https://github.com/striner/javaCode/blob/master/Minimum%20number%20of%20rotation%20array


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值