Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.java
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).数组
Find the minimum element.this
You may assume no duplicate exists in the array.spa
给定一个数组,数组可能被旋转了,可是在旋转以前是递增有序的,找出该数组的的最小值。(数组没有重复值)code
复杂度等价于一个二分查找,是O(logn),空间上只有四个变量维护二分和结果,因此是O(1)。element
采用二分查找的方法进行查找。数组的第一个元素要大于最后一个元素,由于数组是递增的,若是不小于则第一个元素就是最小的元素。若是不小于,初始化high=0,high=len-1,则取中间数mid,若是中间数大于high指向的元素,则说明小数存在后半段,则将high指向mid,不然将high指向mid,继续进行寻找。leetcode
只须要判断是否为递增序列或者是否只有一个元素特殊状况便可,添加一句,if (nums[low] <= nums[high]) return nums[low];继续二分查找。等号判断只有一个元素状况,小于判断递增序列。注意:若是中间元素小于最左边元素,则右部分为有序数组。说明此时中间元素已经在最小值右侧,否则不会小于最左侧元素
get
154. Find Minimum in Rotated Sorted Array II it
Follow up for "Find Minimum in Rotated Sorted Array":
What if duplicates are allowed?ioWould this affect the run-time complexity? How and why?
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
Find the minimum element.
The array may contain duplicates.
给定一个数组,数组可能被旋转了,可是在旋转以前是递增有序的,找出该数组的的最小值。(数组有重复值)
两道题解法同样,有重复值只要判断 low high mid三者指向的元素是否相等,相等就退化为O(N)复杂度。
public int search(int[] nums, int target) { if (nums == null || nums.length < target) return 0; int low = 0; int res = 0; int high = nums.length - 1; if (nums[low] <= nums[high]) res = Arrays.binarySearch(nums, target); else { int m = findMin(nums); System.out.println(m); res = Arrays.binarySearch(nums, 0, m, target); if (res < 0) res = Arrays.binarySearch(nums, m, high + 1, target); } if (res < 0) return -1; else return res; } public int findMin(int[] nums) { // ask interviewer which value should return: // Integer.MIN_VALUE or throw a Exception. if (nums == null || nums.length == 0) return -1; int low = 0; int mid = 0; int high = nums.length - 1; while (nums[low] >= nums[high]) { // 表示找到 if (high - low == 1) { mid = high; break; } mid = (low + high) / 2; // 若是三个数字相等须要遍历整个数字查找最小值 if (nums[mid] == nums[low] && nums[mid] == nums[high]) return MinOrder(nums, low, high); // 处于递增子序列中,最小值在右侧 if (nums[mid] >= nums[low]) low = mid; else // 处于递减子序列中,最小值在左侧 high = mid; } return nums[mid]; } // 遍历整个数组求最小值 private int MinOrder(int[] nums, int low, int high) { int min = nums[low]; for (int i = low + 1; i <= high; i++) min = Math.min(min, nums[i]); return min; }网上参考:http://www.programcreek.com/2014/03/leetcode-find-minimum-in-rotated-sorted-array-ii-java/
public class Solution { public int findMin(int[] num) { return findMin(num, 0, num.length-1); } public int findMin(int[] num, int left, int right){ if(right==left){ return num[left]; } if(right == left +1){ return Math.min(num[left], num[right]); } // 3 3 1 3 3 3 int middle = (right-left)/2 + left; // already sorted if(num[right] > num[left]){ return num[left]; //right shift one }else if(num[right] == num[left]){ return findMin(num, left+1, right); //go right }else if(num[middle] >= num[left]){ return findMin(num, middle, right); //go left }else{ return findMin(num, left, middle); } }