import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param nums int整型一维数组 * @return int整型 */ public int minNumberInRotateArray (int[] nums) { // write code here // 整个问题本是上是在找数组中唯一存在的极小值,采取二分法解决 // 算法的时间复杂度O(logN),额外空间复杂度O(1) int n = nums.length; if (n == 1) { // 如果只有一个元素 return nums[0]; } if (n == 2) { // 如果只有两个元素 return Math.min(nums[0], nums[1]); } // 确保有三个以上的元素 int l = 0; int r = n - 1; // 采用二分思想,任务是找到这样一个转折点[↗……↗(↘index)↗……↗],其特征是左边比它大,右边也比它大 int min = nums[l]; while (l < r) { // 因为数组非递减,且涉及到右划l // 所以采用一个变量min时刻与当前最左的l元素比较总不是坏事 min = Math.min(min, nums[l]); int mid = (l + r) / 2; if (nums[l] > nums[mid]) { // 如果mid处比最左处要小,即[↗……↗(↘index)↗……mid……↗],说明局部最小值一定在左半区(或mid本身) r = mid; } else if (nums[l] < nums[mid]) { // 如果mid处比最左处要大,即[↗……mid……↗(↘index)↗……↗],说明局部最小值一定在右半区(必不包括mid) l = mid + 1; } else { // 如果mid处与最左处相等,即[-->……mid……-->(↘index)↗……-->],或[-->……-->(↘index)↗……-->……mid……-->],在左还是在右不能确定 // 但是!至少说明l处一定不是极小值点,此时l往右移一位,缩小范围即可 l++; } } return Math.min(min, nums[l]); } }