剑指offer(java)——在递增旋转数组中查找最小值

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

题目关键词:递增排序、旋转。

分析:上图是符合题目要求的三种数组,第一种是很正规的一种情况:数组因为旋转的原因,分成两个递增数组,而最小值位于后面数组的第一个值。针对此题,首先要想到的是采用二分查找,第二点非常重要的一点就是想到旋转数组条件特殊的数组,加以处理。(一个好的开发人员应该要是一个好的测试人员)

上图2是一个排好序的数组,是一种特殊的旋转数组,对于此种情况,直接返回数组的第一个元素即可,代码中体现为mid的初始值为start;上图三如果start、end、mid对应的值相等的情况二分无法确定最小值在哪部分,此时可以采用顺序查找。

package com.example;

public class FindMin {
	
	public static void main(String[] args) {
		int[] nums={6,7,8,1,2,3,4,5};//{1,0,1,1,1};//{1,2,3,4,5,6,7,8};//{3,4,5,1,2};
		int minNUm=findMin(nums);
		System.out.println("数组中最小的数"+minNUm);
	}
	/**
	 * 查找数组中的最小值
	 * @param nums 递增排序的旋转数组
	 * @return  数组中的最小值
	 */
	public static int findMin(int[] nums){
		//判空处理
		if(nums==null||nums.length<0){
			throw new IllegalArgumentException("输入数组参数非法");
		}
		int start=0;//开始指针
		int end=nums.length-1;//结束指针
		int mid=start; //如果数组本来就是排好序的,则数组的第一个元素就是数组的最小值
		while(nums[start]>=nums[end]){
			if(end-start==1){//循环结束条件
				mid=end;
				break;
			}
			mid=(start+end)/2;
			//如果start,end,mid指向的数组相等,则只能是采用顺序查找
			if(nums[start]==nums[end]&&nums[start]==nums[mid]){
				return minInOrder(nums,start,end);
			}
			
			if(nums[start]<=nums[mid]){
				start=mid;
			}else if(nums[end]>=nums[mid]){
				end=mid;
			}
		}
		return nums[mid];
	}

	private static int minInOrder(int[] nums, int start, int end) {
		int result=nums[start];
		for(int i=start+1;i<=end;i++){
			if(result>nums[i]){
				result=nums[i];
			}
		}
		return result;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章