小知识,大挑战!本文正在参与「程序员必备小知识」创作活动。
问题
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
力扣链接
考察要点
考察对于二分查找算法的深入理解, 不要只局限于单一用途
考察我们思考问题的严谨与全面性, 要做到一丝不苟
首先要认识什么是旋转数组?
旋转数组在数组的分布上又可以分为两个有序的子数组
前面数组中的元素大于等于后面数组中的元素
思路
-
定义指向最左边元素的索引left, 指向最右边元素的索引right和指向中间的索引mid
-
判断中间索引指向的元素
它如果大于right索引指向的元素, 则表明mid索引它属于第一个数组的, 则现在将left指向mid+1的位置
它如果小于right索引指向的元素, 则表明mid索引它属于第二个数组的, 则现在将right指向mid的位置
它如果等于right索引指向的元素, 则无法判断mid索引指向的元素属于哪个子数组, 则现在将right索引减1
-
当left>=right时, 则right索引指向的元素就是要找的最小元素
代码
public int minArray(int[] list) {
int length = list.length;
// 定义三个索引
int left = 0;
int right = length - 1;
int mid = (right - left) / 2;
// 当left索引大于等于right时, 则不再查找
while (left < right) {
mid = (right + left) / 2;
// 中间索引属于第二个子数组
if (list[mid] < list[right]) {
right = mid;
} else if (list[mid] > list[right]) { // 中间索引属于第一个子数组
left = mid + 1;
} else { // 无法判断中间索引属于哪个子数组
right--;
}
}
return list[right];
}
总结
本题考察我们对于二分查找算法的熟练度. 之前我对二分查找的认识还仅局限于整体有序的一组数据中, 现在让我知道了二分查找有更多的用途.
在解决问题时, 我们不要单单只考虑普通的情况, 不要考虑特殊情况, 边界的判断, 测试用例的完善.