一题一算法2018-02-08(旋转数组的最小数字)

题目:旋转数组的最小数字

题目描述:

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

题目思考:

首先,我们看到的非递减排序数组,实质上就是一个递增数组,一个递增数组将前面的一部分挪到后面去,这样就形成了两个递增的数组,前面一个数组中的所有元素都要比后一个大,那么问题就有了实质的变化,就是求这两个数组的分界线,此时整个数组的前一个元素大于后面一个元素的时候我们就可以知道,此时后面一个元素就是整个数组的最小值。

题目思路一:

最简单最之际的方法,也是我们最先想到的,但是却是最不推荐的,直接遍历比较大小。

题目思路二:

题目思考中的方式,循环遍历比较数组中前后两个元素,当遇到后一个比前一个小的时候,将后一个返回此时就是最小的元素。

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size() == 0)
            return 0;
        for(int i = 0; i < rotateArray.size()-1; i++){
            if(rotateArray[i]>rotateArray[i+1]){
                return rotateArray[i+1];
            }
        }
        return rotateArray[0];
    }
};

题目思路三:

此种解法是从二分法出来的,通过二分法不断逼近最小的值,二分法从时间复杂度上来说是O(log(n)),而思路二的时间复杂度是O(n),这种方式来说更加快捷。


1、先判断数组是否为空,为空返回0;
2、我们定义beg、end、mid三个指针分别指向数组的头、尾、中部;
3、判断数组是否旋转,就是array[beg]>array[end],当出现这种状况的时候就说明数组旋转,没有的话就说明数组没有旋转,此时我们只输出array[0]即可。
4、当array[mid]>=array[beg]的时候,说明从beg到mid这部分还是递增的数组,那么此时beg= mid,将数组的范围缩小,变成mid~max,继续循环。
5、当array[mid]<=array[end]的时候,说明从mid到end这部分是递增的数组,此时end = mid,将数组的范围缩小,变成beg~mid,继续循环。

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size() == 0)
            return 0;
        int beg = 0;
        int end = rotateArray.size() - 1;
        int mid =  0;
        while(rotateArray[beg] >= rotateArray [end]){
            
            if((end - beg) == 1){
                mid = end;
                break;
            } 
            mid = (end + beg)/2;
            if(rotateArray[beg] <= rotateArray[mid]){
                beg = mid;
            }
            if(rotateArray[end] >= rotateArray[mid]){
                end = mid;
            }
            
        }
        return rotateArray[mid];
    }
};
此思路存在的容易犯错的地方:因为数组是分成2段的,我们只能知道这两段的单调性,数组分成前后两半段递增,所以我们只能分别判断array[beg] 和 array[end]同array[mid]大小比较,这样我们才能判断其单调性,单调递增就是mid这个值不断逼近最小值的方法。

思路四:

看到题干我们知道数组书vector,我们用STL的函数将数组排序,直接输出array[0]即可。

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        sort(rotateArray.begin(),rotateArray.end());
        return rotateArray[0];
    }
};

题目延伸:

给定一个有序数组,如{1,2,3,4,5,6,7,8,9},我们将对这个数组进行选择,未知从什么位置旋转。下面给出一个可能的旋转结果。如{4,5,6,7,8,9,1,2,3},我们可以理解为它从元素4位置开始旋转。之后给定一个指定的数字n,让我们从{4,5,6,7,8,9,1,2,3}这个数组中找出它的位置,要求时间复杂度尽可能的低。

延伸思路一:

从头开始遍历数组比较大小,返回n的位置。

延伸思路二:

使用STL的方法find()

延伸思路三:二分法

我可以使用上面类似的方法:

解题的思路和上面类似,分段判断,然后二分法逼近。

int search(int n,int[] array){
        int low = 0;        
        int high = array.length-1;
        while(low<=high){
            int middle = (low+high)/2;
            if(array[middle]==n) return middle;
            if(array[middle]>array[low]){  //left is order
                if(n<=array[middle]&&n>=array[low]){
                    high = middle-1;
                }else {
                    low = middle+1;
                }
            }else {         
                if(n>=array[middle]&&n<=array[high]){
                    low = middle+1;
                }else {
                    high = middle-1;
                }
            }
        }
        return -1;  
    } 
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容