假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7]
可能变为 [4,5,6,7,0,1,2]
)。
请找出其中最小的元素。
注意数组中可能存在重复的元素。
示例 1: 输入: [1,3,5] 输出: 1
示例 2: 输入: [2,2,2,0,1] 输出: 0
思路:
{2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 2} 和 {2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2}, 我们发现,当第一个数字和最后一个数字,还有中间那个数字全部相等的时候,二分查找法就崩溃了,因为它无法判断到底该去左半边还是右半边。这种情况下,我们将左指针右移一位,略过一个相同数字,这对结果不会产生影响,因为我们只是去掉了一个相同的,然后对剩余的部分继续用二分查找法,在最坏的情况下,比如数组所有元素都相同,时间复杂度会升到O(n)。
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
int mid = 0;
while(nums[left] >= nums[right]){
if(right - left == 1){
mid = right;
break;
}
mid = left + (right - left) / 2;
if(nums[mid] == nums[left] && nums[mid] == nums[right]){
int result = nums[left];
for(int i = left + 1; i <= right; i++){
if(result > nums[i]){
result = nums[i];
}
}
return result;
}
if(nums[mid] <= nums[right]) right = mid;
if(nums[mid] >= nums[left]) left = mid;
}
return nums[mid];
}