【剑指offer】刷题记录-旋转数组的最小数字

题目描述

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

思路1:直接遍历数组,找最小的数。

// 旋转数组的最小数字
public class Solution {
	public int minNumberInRotateArray(int[] array) {
		if (array == null || array.length == 0) {
			return 0;
		}
		int min = array[0];
		for (int i = 0; i < array.length; i++) {
			if (array[i] < min) {
				min = array[i];
			}
		}
		return min;
	}
}

缺点:没有利用旋转数组的特点。时间复杂度高。

思路2:对旋转数组来说,实际上我们可以将它划分为两个排序的子数组,而且前面子数组的元素都大于等于后面子数组的元素,并且最小元素是这两个子数组的分界。再利用二分查找的思想即可。

// 旋转数组的最小数字
public class Solution {
	public int minNumberInRotateArray(int[] array) {
		if (array == null || array.length == 0) {
			return 0;
		}
		int startIndex = 0;
		int endIndex = array.length - 1;
		int midIndex = startIndex;
		// 当数组发生了旋转时
		while (array[startIndex] >= array[endIndex]) {
			if (endIndex - startIndex <= 1) {
				midIndex = endIndex;
				break;
			}
			midIndex = (startIndex + endIndex) / 2;
			// 如果中间的数位于数组1
			if (array[startIndex] <= array[midIndex]) {
				startIndex = midIndex;
			}
			// 如果中间的数位于数组2
			if (array[endIndex] >= array[midIndex]) {
				endIndex = midIndex;
			}
			// 如果中间的数既等于startIndex上的数 也等于endIndex上的数
			if (array[midIndex] == array[startIndex] && array[midIndex] == array[endIndex]) {
				return minOfArray(array, startIndex, endIndex);
			}
		}
		return array[midIndex];

	}

	public int minOfArray(int[] array, int index1, int index2) {
		int result = array[index1];
		for (int i = index1 + 1; i < index2; i++) {
			if (array[i] < result) {
				result = array[i];
			}
		}
		return result;
	}
}

猜你喜欢

转载自blog.csdn.net/Littlecome/article/details/81977682