Leetcode 154. Find Minimum in Rotated Sorted Array II

题目如下:

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.

Example 1:

Input: [1,3,5]
Output: 1

Example 2:

Input: [2,2,2,0,1]
Output: 0

Note:

  • This is a follow up problem to Find Minimum in Rotated Sorted Array.
  • Would allow duplicates affect the run-time complexity? How and why?

 题目很简单,解法也不难,问题在于重复的数字,首先我们来看看不重复的该怎么解。

首先初始数列是有序的,但是可能会从某个数字开始将数列分为两段,然后把整个后面这一段放到另一段前面。

即 123456789 变为 789123456

这个问题是可以用logn的复杂度解决的,使用二分法的思想,找到中间的那个数,这里是2,那么我们的目标是找到1,我们发现这个1在前半部分,那么后面的部分我们就不管了,现在这个数列变成了 78912 ,重复这个过程即可。至于为什么可以这么做,原因在于有序。截断的话前面那部分是永远大于等于后面这部分的,当我们去掉无关紧要的部分后有序性是不会改变的,我们的目标也就没有改变。

这道题只要好好利用有序这个点就可以做到很低的复杂度。但是正如题干里面需要我们注意的那一个问题问的那样,重复会给复杂度带来怎样的改变,答案是会大大增加复杂度的。

一个样例里面的例子为10 10 10 2 10,使用我们上面的方法是没有办法排除无关紧要的那部分的,所以我们需要两边都执行一次,这样直接导致复杂度变成了nlogn,对,和归并排序一样,其实思路就是归并的思路。

代码如下:

class Solution {
public:
    int findMin(vector& nums) {
        int len=nums.size();
		int r=0,l=len-1;
		if(nums[r]&nums,int r,int l)
    {
    	while(r=nums[r])
			{
				r=mid;
			}
			else if(nums[mid]<=nums[l])
			{
				l=mid;
			}
			
		}
		return nums[r];
	}
};

代码很简单就不解释了,下面给出leetcode上面最快的方法

static auto x=[](){
    std::ios::sync_with_stdio(false);
    cin.tie(NULL);
    return nullptr;
}();
class Solution {
public:
    int findMin(vector& nums) {
        int low = 0,end = nums.size()-1;
        
        while(lownums[end])low = mid+1;
            else if(nums[mid]==nums[end]) end--;
            else end = mid;
        }
        cout<

至于为什么快我就不是很理解了,复杂度应该是n,和直接线性扫描的复杂度差不多(当然了,这是在绝大部分都是相同数字的情况下),他在处理重复元素时的思路直接删除最后一个相同元素即可。

你可能感兴趣的:(c++算法)