剑指offer(6)旋转数组中的最小数字

本文介绍了一种寻找旋转数组中最小元素的算法,提供了两种实现方法:遍历法和二分查找法。遍历法简单直接,二分查找法更高效,适用于非减排序的旋转数组,特别讨论了特殊情况下如何处理。
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));
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值