153. Find Minimum in Rotated Sorted Array

本文介绍了一种在已排序并旋转的数组中寻找最小元素的方法。通过二分查找技术,可以高效地找到该元素,时间复杂度达到O(logn)。文章提供了两种实现思路,并附带代码示例。
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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值