剑指offer之面试题11:旋转矩阵的最小数字

旋转矩阵的最小数字

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

思路:

  • 和二分查找一样,我们用两个指针分别指向数组的第一个元素和最后一个元素。接着我们寻找数组中间的元素。如果该中间元素位于前面的递增子数组,那么它应该大于或者等于第一个指针指向的元素。此时数组中最小的元素应该位于该中间元素的后面。这样我们可以把第一个指针指向该中间元素,这样可以缩小寻找的范围。移动之后第一个指针仍然位于前面的递增子数组。
  • 同样,如果中间元素位于前面的递增子数组,那么它应该大于或者等于第一个元素指向的元素。此时该数组中最小的元素应该位于该中间元素的前面。我们把第二个指针移动到中间元素的位置,也可以缩小范围。
  • 重复①②步知道 right - left = 1 为止。
  • 特殊情况 1:旋转矩阵旋转了 0 个元素(即根本没有旋转)。
  • 特使情况 2:0 1 1 1 1 旋转两个元素之后变成 1 1 1 0 1。此时左边元素、右边元素和中间元素均是1,无法判断这个 1 是属于左边的还是属于右边的。

代码实现:

public static int getMin(int[] arr) {
	int left = 0;
	int right = arr.length - 1;
	if(arr[left] < arr[right]) {
		return arr[left];
	}
	while(right - left != 1) {
		int mid = left + (right - left) / 2;
		if(arr[mid] == arr[left] && arr[mid] == arr[right]) {
			int index = left;
			int min = arr[index];
			for(int i = left; i <= right; i++) {
				if(min > arr[i]) {
					min = arr[i];
					index = i;
				}
			}
			return arr[index];
		} else {
			if(arr[mid] >= arr[left]) {
				left = mid;
			} else if(arr[mid] <= arr[right]) {
				right = mid;
			}
		}
	}
	return arr[right];
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值