package com.jianzhioffer.minnumberinrotatearray;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。
* 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 给出的所有元素都大于0,若数组大小为0,请返回0。
*
* @author hexiaoli 思考: 1)遍历,找到第一个下降的元素 2)旋转数组已经将数组分为递增和递减序列。(不建议,未通过~说算法复杂度过大)
* 需要头尾指针,如果头指针元素比头指针指的后一个元素小的话,头指针++ 如果尾指针元素比尾指针指的前一个元素大的话,尾指针++
* 直到头尾指针差1的时候,尾指针所指元素为最小 但这个要防止(10111)和(11101)两种情况
*
*/
public class Main {
public static int minNumberInRotateArray1(int[] array) {
// 边界情况
if (array == null || array.length <= 0) {
return 0;
}
if (array.length == 1) {
return array[0];
}
for (int i = 1; i < array.length; i++) {
// 遍历数组,若当前元素大于它下一个元素,则下一个元素即为最小元素
if (array[i - 1] > array[i]) {
return array[i];
} else if (i == array.length - 1) {
// 若倒数第二个元素没有大于最后一个元素,
// 则该数组为单纯的升序数组,最小元素为第一个元素
return array[0];
}
}
return 0;
}
public static int minNumberInRotateArray2(int[] array) {
// 边界情况
if (array == null || array.length <= 0) {
return 0;
}
if (array.length == 1) {
return array[0];
}
// 设置首尾指针,索引值
int head = 0;
int tail = array.length - 1;
int index = head;
while (head < tail && array[head] >= array[tail]) {
// 首尾相差1即找到
if (tail - head == 1) {
index = tail;
break;
}
// 指向中间,类似于二分查找
// index = ((tail - head) >> 1) + head;
// index = (tail - head) / 2 + head;通过
index = (tail + head) >> 1;
// 如果三个指针指向的元素相同,只能顺序查找
if (array[head] == array[index] && array[head] == array[tail]) {
return Order(array, head, tail);
}
//
if (array[head] <= array[index]) {
head = index;
} else if (array[tail] >= array[index]) {
tail = index;
}
}
return array[index];
}
public static int Order(int[] array, int head, int tail) {
int result = array[head];
for (int i = head + 1; i <= tail; i++) {
if (result > array[i]) {
result = array[i];
}
}
return result;
}
public static void main(String[] args) throws IOException {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
// 用nextLine()可以读取一整行,包括了空格,next()却不能读取空格
String str = input.readLine();
String arr[] = str.split(" ");// 拆分字符串成字符串数组
int array[] = new int[arr.length];
for (int j = 0; j < array.length; j++) {
array[j] = Integer.parseInt(arr[j]);
}
System.out.println(minNumberInRotateArray1(array));
System.out.println(minNumberInRotateArray2(array));
}
}