153. Find Minimum in Rotated Sorted Array

来源:互联网 发布:淘宝 雅诗兰黛 小样 假 编辑:程序博客网 时间:2024/05/16 14:43

Question

Suppose a sorted array 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.

You may assume no duplicate exists in the array.

思路一

这个可以用最笨的办法,找到最小的数就可以了,遍历一边就行了。现在的情况是数组是排好序且是旋转的,就可以用别的办法了。

思路二

利用二分查找的思路,The minimum element must satisfy one of two conditions: 1) If rotate, A[min] < A[min - 1]; 2) If not, A[0]. Therefore, we can use binary search: check the middle element, if it is less than previous one, then it is minimum. If not, there are 2 conditions as well: If it is greater than both left and right element, then minimum element should be on its right, otherwise on its left.

代码

public class Solution {    public int findMin(int[] nums) {        if(nums == null || nums.length == 0)            return 0;        return find_min(nums,0,nums.length - 1);    }    public int find_min(int[] nums,int start,int end){        int mid = (start + end)/2;        if(start == end)            return nums[start];        else if(start + 1 == end){            if(nums[start] < nums[end])                return nums[start];            else                return nums[end];        }        else{            if(nums[mid] < nums[mid - 1])                return nums[mid];            else if(nums[mid] > nums[start] && nums[mid] > nums[end])                return find_min(nums,mid + 1,end);            else                 return find_min(nums,start,mid - 1);        }    }}

结果及分析

差不多是最优的结果,时间复杂度为O(logn),这是二分法的时间复杂度比遍历一遍的复杂度低很多。

Your runtime beats 4.10% of java submissions.

二刷THOUGHT II

思路还是二分法的思路,不过之前的思路太过于复杂,其实多在算草纸上跑几遍,就可以找到更好的思路。首先检验是不是
顺序的数组,如果nums[0] < nums[n-1],说明是顺序排列的,返回nums[0]即可,否则的话按照旋转之后的进行查找。如果nums[mid] 大于 nums[begain],说明最小值在后半段,则begin = mid,若nums[mid] 小于nums[begin],说明在前半段,所以end=mid;当相等的时候,说明就剩下两个数,返回较小的那个就行了。

CODE

public class Solution {    public int findMin(int[] nums) {        if(nums == null || nums.length == 0)            return 0;        int n = nums.length;        if(nums[0] < nums[n - 1])            return nums[0];        int begain = 0,end = n -1,mid = 0;        while(begain <= end){            mid = (begain + end)/2;            if(nums[mid] > nums[begain])                begain = mid;            else if(nums[mid] < nums[begain])                end = mid;            else{                return Math.min(nums[begain],nums[end]);            }        }        return nums[mid];    }}
RESULT

Your runtime beats 58.44% of java submissions.

0 0
原创粉丝点击