【LeetCode】Find Minimum In Rotated Sorted Array 1 and 2

46 篇文章 0 订阅
38 篇文章 0 订阅

【题目】

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。

【分析】

本来自己还想了一个特别麻烦的办法,大概用了一点二分法的思路,就是从中间的元素开始和两头的比较。

start是第一个元素,end是最后一个元素,mid是中间的元素的位置

1.先判断start和end的大小,如果start<end,说明array是有序的,并没有被调换,此时直接返回start

2.否则,就是调换的, 比较中间元素和两边元素的关系

    中间元素小于最后的元素,说明该元素属于小号那一拨,更小的元素可能还在前面,所以MID位置-1,继续判断,直到违规,或者到达边界

返回mid+1

否则,就是属于大的那一拨,mid++,直到<start就是最小的那个元素.

【代码1】我的代码

public int findMin(int[] num) {
        int start=num[0];
		int end=num[num.length-1];
		if(start<end) return start;
		int mid=num.length/2;
		if(num[mid]<end){
		while(num[mid]<end&&mid>0){
			mid--;	
		}
		return num[mid+1];
		}
		while(num[mid]>start&&mid<num.length-1){
			mid++;
		}
		return num[mid];
    }


【代码2】

 minimum is at Ai where Ai-1 > Ai. 

  public int findMin(int[] num) {
        for(int i=1; i<num.length; i++) {
            if(num[i] < num[i-1]) return num[i];
        }
        return num[0];
    }

【代码3】

Looking at subarray with index [start,end]. We can find out that if the first member is less than the last member, there's no rotation in the array. So we could directly return the first element in this subarray.

If the first element is larger than the last one, then we compute the element in the middle, and compare it with the first element. If value of the element in the middle is larger than the first element, we know the rotation is at the second half of this array. Else, it is in the first half in the array.


 int findMin(vector<int> &num) {
        int start=0,end=num.size()-1;

        while (start<end) {
            if (num[start]<num[end])
                return num[start];

            int mid = (start+end)/2;

            if (num[mid]>=num[start]) {
                start = mid+1;
            } else {
                end = mid;
            }
        }

        return num[start];
    }
【官方答案】

The minimum is at Ai where Ai-1 > Ai. Notice that if we subdivide the array into two, one will always be sorted, while the other contains the minimum.

Imagine we have an array [1,2,3,4,5,6,7] (See graph 1) which was being rotated 3 steps to the right [5,6,7,1,2,3,4] (See graph 2). Let’s say we subdivide the array at point k to two subarrays [AL, AL+1, …, Ak], [Ak+1, …, AR].

If the sorted array is not rotated, then AL < AR then we could return AL as the minimum immediately.

Otherwise for a sorted array that was rotated at least one step, AL must always be greater than AR.

Let’s assume we choose M1 as the dividing point. Since AM1 > AR, we know that each element in [AL … AM1] is greater than AR (Remember that AL > AR?). Therefore, the minimum value must locate in [AM1+1 … AR].

On the other hand, let’s assume we choose M2 as the dividing point. Since AM2 ¬≤ AR, we know that each element in [AM2+1 … AR] is greater than AM2. Therefore, the minimum point must locate in [AL … AM2].

As we are discarding half of the elements at each step, the runtime complexity is O(log n).

To understand the correct terminating condition, we look at two elements. Let us choose the lower median as M = (L + R) / 2. Therefore, if there are two elements, it will choose AL as the first element.

There are two cases for two elements:

A = [1,2]
B = [2,1]

For A, 1 < 2 => AM < AR, and therefore it will set R = M => R = 0.

For B, 2 > 1 => AM > AR, and therefore it will set L = M + 1 => L = 1.

Therefore, it is clear that when L == R, we have found the minimum element.


[follow up]

Find minimum in Rotated Array

Follow up for "Find Minimum in Rotated Sorted Array":
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

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.

The array may contain duplicates.


public class Solution {
    public int findMin(int[] num) {
        int min = num[0];
        for (int i = 1; i < num.length; i++) {
            if (num[i] < min)
                min = num[i];
        }
        return min;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值