Leetcode:Find Minimum in Rotated Sorted Array II

来源:互联网 发布:网络攻防基础 编辑:程序博客网 时间:2024/04/29 05:23

原题链接:https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii

我在github上的leetcode仓库:https://github.com/cooljacket/leetcodes

题意

这道题的第一个版本已经写了博客:http://blog.csdn.net/Jacketinsysu/article/details/52299090

第二版本只是多了一个限制:数组里可以有重复的元素

思路

用low,high和mid分别表示左端、右端和区间中点。

如下图所示,当nums[mid] == nums[high]为true时,该怎么办呢?这个时候,最小值可能位于区间[mid1, high]上,也可能位于[low, mid2]上。

《剑指offer》的策略

在区间[low, high]上线性查找,这的确不会错过,也可行,不过写起来麻烦,代码长了好多行。

我的策略

我的方法也是线性查找,不过不是在[low, high]之间,而是简单–high就好了!

首先,–high是否能够解决这个问题?相当于从右边缩减查找区间的范围,这确实是可行的,也不会遗漏。

其次,为什么不++low呢?举个例子:{4, 4, 4, 4, 0, 1, 1}
第一次查找:[0, 6],mid=3,nums[3] = 4 > nums[high],所以low变成mid+1=4;
第二次查找:[4, 6],mid=5,nums[5] = 1 == nums[high],这个时候++low吗????那查找区间就变成[5, 6]了,错过了最小值了。。。

那到底是为什么不能++low呢?原因在于我们是拿nums[mid]和nums[high]去做比较的,跟nums[low]没有一毛钱的直接关系,所以不能用右区间的情况来决定左区间的动态。

说直观点,就是,比如张三偷东西了,警察来了,人赃俱获,然后把李四给抓走了,你说冤不冤,哈哈~

性能

最后,评价一下我这个方法的性能,最差的情况也是O(n)的,不过平均情况要比上面的策略好,至于为什么就不用多说了吧?(因为不是一遇到相等的情况就“无脑线性找”,而是进一步,看看能不能继续做折半查找,见下面的代码)。

代码

猪一般的优雅,哈哈!

class Solution {public:    int findMin(vector<int>& nums) {        int low = 0, high = nums.size() - 1, mid;        while (low < high) {            mid = (low + high) >> 1;            if (nums[mid] > nums[high])                low = mid + 1;            else if (nums[mid] < nums[high])                high = mid;            else // 没错,就是这么简单!                --high;        }        return nums[low];    }};

╭︿︿︿╮
{/ o o /}
( (oo) )
︶ ︶︶
另,如果要跟《剑指offer》里的做法一样的话,也行,得写这……么长:

class Solution {public:    int findMin(vector<int>& nums) {        int low = 0, high = nums.size() - 1, mid;        while (low < high) {            mid = (low + high) >> 1;            if (nums[mid] == nums[low] && nums[mid] == nums[high])                return linearSearch(nums, low, high);            if (nums[mid] > nums[high])                low = mid + 1;            else if (nums[mid] < nums[high])                high = mid;            else                --high;        }        return nums[low];    }private:    int linearSearch(const vector<int>& nums, int low, int high) {        int minNum = nums[low];        for (int i = low+1; i <= high; ++i) {            if (nums[i] < minNum)                minNum = nums[i];        }        return minNum;    }};
1 0