[剑指 Offer 第 2 版第 11 题] “旋转数组的最小数字”做题记录
- 牛客网 online judge 地址:https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组 {3,4,5,1,2} 为 {1,2,3,4,5} 的一个旋转,该数组的最小值为 1 。 NOTE:给出的所有元素都大于 0 ,若数组大小为 0 ,请返回 0 。
求解思路与关键
- 可以使用二分查找的思想,因为最小的数字很可能出现在首位,从后向前扫描是求解这道题的重要技巧,否则需要分类讨论,就变得麻烦了(即让后面的指针向前移动)。
参考解答
参考解答1
public class Solution {
// 虽然可以通过,但是 O(n) 的复杂度并不理想
public int minNumberInRotateArray(int[] array) {
// {3,4,5,1,2}
// 1 2 3 4 5
int len = array.length;
for (int i = 1; i < len - 1; i++) {
if (array[i] < array[i - 1]) {
return array[i];
}
}
// 如果走到这里,说明数组是升序的,直接返回第 0 号索引的元素就可以了
return array[0];
}
public static void main(String[] args) {
// int[] nums = new int[]{3, 4, 5, 1, 2};
int[] nums = new int[]{1, 2, 3, 4, 5};
Solution solution = new Solution();
int minNumberInRotateArray = solution.minNumberInRotateArray(nums);
System.out.println(minNumberInRotateArray);
}
}
参考解答2
public class Solution2 {
public int minNumberInRotateArray(int[] array) {
int len = array.length;
if (len == 0) {
return 0;
}
int first = 0;
int last = len - 1;
while (first < last) {
int mid = first + (last - first) / 2;
if (array[mid] > array[last]) {
first = mid + 1;
} else if (array[mid] == array[last]) {
last = last - 1;
} else {
last = mid;
}
}
return array[first];
}
public static void main(String[] args) {
// int[] nums = new int[]{3};
// int[] nums = new int[]{3, 4, 5, 6, 7, 8, 9, 1, 2};
// int[] nums = new int[]{1, 2, 3, 4, 5};
int[] nums = new int[]{2, 2, 2, 1, 2};
Solution2 solution2 = new Solution2();
int minNumberInRotateArray = solution2.minNumberInRotateArray(nums);
System.out.println(minNumberInRotateArray);
}
}