剑指 offer——面试题8求旋转数组的最小值
时间:2022-05-03
本文章向大家介绍剑指 offer——面试题8求旋转数组的最小值,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:将一个非递减序列的某一处切一刀,再把前半段序列放到后半段序列的后面,这样组成的新序列叫做“旋转数组”。要求获取一个旋转数组的最小值。
这本质上是一个求最值的问题,最简单的方法就是顺序遍历数组,从中找出最小值,该方法的时间复杂度为O(n)。但这种方法会被面试官鄙视的,所以我们寻找更为高效的办法。
这道题给的数组是一个“旋转数组”,旋转数组是将一个非递减数组切成两个数组后重新组装而成的,旋转数组的前半段所有元素值均大于等于后半段元素的值,两段的分界点就是最小值。
要寻找分界点,可以采用对半搜索,若第一个元素的值小于中点元素值,则断点在后半段,否则断点在前半段,若当前数组只剩下两个元素时,找出其中较小一个即是答案。时间复杂度为O(logn)。
下面我们来考虑一些特殊情况:
- 若序列本身有序,若仍然采用上述算法,则会将倒数第二个元素误判为最小值。因此,如果数组的第一个元素小于最后一个元素时就认为数组有序,第一个元素即为最小值。
- 若数组的第一个元素和最后一个元素相等,则断点可能在中点的前半段,也可能在后半段,此时需要遍历数组求得最小值。
/**
* 获取旋转数组的最小值
* 旋转数组:在一个递增数组的任意一个位置切一刀,
* 再把第一个数组放到第二个数组的后面,
* 这样生成的数组就是旋转数组。
* @author chibozhou
*/
public class GetMin {
private static int min;
/**
* 获取旋转数组的最小值
* @param arr 输入的旋转数组
* @param start 数组的起始下标
* @param end 数组的结束下标
* @param min 搜索结果最小值
*/
public static void getMin(int[] arr,int start,int end,Int min){
//健壮性判断,数组不能为空
if(arr==null || arr.length<=0){
System.out.println("数组为空!");
return ;
}
//健壮性判断,start不能>end
if(start<0 || end<0 || start>end){
System.out.println("start、end非法!");
return;
}
//健壮性判断,min不能为空
if(min==null){
System.out.println("min为空!");
return;
}
//若数组首<尾,则本身有序
if(arr[start]<arr[end]){
System.out.println("数组本身有序");
min.setMin(arr[start]);
return;
}
//若数组首=尾,则断点位置不确定
if(arr[start]==arr[end]){
//遍历数组,寻找最小值
int i = start;
while(arr[i]<=arr[i+1] && i<end){
i++;
}
//输出最小值
min.setMin(arr[++i]);
}
//若数组首>尾,则断点位置可以确定(要么在中点前,要么在中点后)
if(arr[start]>arr[end]){
//获取中点
int mid = (start+end)/2;
//若数组首<中点,则断点在后半段
if(arr[start]<arr[mid]){
start = mid+1;
}
else if(arr[start]>arr[end]){
end = mid-1;
}
else{//arr[start]=arr[end]
start = mid+1;
}
//若start和end相邻,则比较一下选出小的
if(start+1==end){
if(arr[start]>arr[end]){
min.setMin(arr[end]);
}
else{
min.setMin(arr[start]);
}
return;
}
getMin(arr,start,end,min);
}
}
/**
* 测试
*/
public static void main(String[] args){
int[] a = new int[]{5,5,5,1,1,1,2,3,4};
Int min = new Int();
getMin(a, 0, a.length-1, min);
}
}
<pre code_snippet_id="1600005" snippet_file_name="blog_20160307_4_6262722" name="code" class="java">/**
* 本类用于设置最小值 * @author chibozhou */class Int{private int min;public int getMin() {return min;}public void setMin(int min) {this.min = min;}}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法