比暴力遍历好一丢丢的解法

旋转数组的最小数字

http://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba

这里提供一个比暴力遍历好一丢丢的解法(最优解还是看官方题解吧,我这个算是暴力解法的小优化版)。

假设一个非递减数组:1 2 3 4 5 6:
它有一个旋转是:3 4 5 6 1 2,可以视为两个非递减序列3 4 5 6和1 2 的组合;
它有一个旋转是:5 6 1 2 3 4,可以视为两个非递减序列5 6和1 2 3 4的组合;
它有一个旋转是:6 1 2 3 4 5,可以视为两个非递减序列6和1 2 3 4 5的组合……
观察规律,我们就有遍历的头猪(xu)了,在数组最小值1的前面,是一个非递减序列。

假设输入一个非递减数组的旋转数组a[0..n],可以设计出以下的遍历逻辑:
for(int i=0; i<=n-1;i++){
if(a[i]<=a[i+1]) {} //如果数组下标从0到i+1可以维持非递减序列,继续遍历(实际代码里这句可以省略)
else /等价于if(a[i]>a[i+1])/ return a[i+1]; //数组下标从0到i+1不再是非递减序列,即a[i]到a[i+1]数值大小是向下跳变的,a[i+1]就是数组最小值,return a[i+1]
}
return a[0]; //没能在for循环里返回,说明a是一个非递减序列,a[0]就是最小的元素,返回a[0]

时间复杂度:O(n),实际用起来会比O(n)小,因为发现了数值大小跳变的地方就返回了。
示例:假设一个非递减数组:1 2 3 4 5 6,n=6;
它有一个旋转是:3 4 5 6 1 2(旋转4次),遍历4次找到结果;
它有一个旋转是:6 1 2 3 4 5(旋转1次),遍历1次找到结果;
直接把1 2 3 4 5 6输进去(旋转0次),不能在for循环中找到结果,说明是一个非递减序列,返回a[0]最小值。遍历了6次。
也就是说一般情况下,一个有序数组被旋转了c次,就要遍历c%n次找到结果(特殊情况c%n==0,要把数组遍历完)。

    public int minNumberInRotateArray(int[] rotateArray)
    {
        // write code here
        if(rotateArray.Length==0) return 0;

        for(int i=0; i<rotateArray.Length-1; i++){
            if(rotateArray[i]>rotateArray[i+1]) return rotateArray[i+1];
        }
        return rotateArray[0];
    }
全部评论

相关推荐

10-09 00:50
已编辑
长江大学 算法工程师
不期而遇的夏天:1.同学你面试评价不错,概率很大,请耐心等待;2.你的排名比较靠前,不要担心,耐心等待;3.问题不大,正在审批,不要着急签其他公司,等等我们!4.预计9月中下旬,安心过节;5.下周会有结果,请耐心等待下;6.可能国庆节前后,一有结果我马上通知你;7.预计10月中旬,再坚持一下;8.正在走流程,就这两天了;9.同学,结果我也不知道,你如果查到了也告诉我一声;10.同学你出线不明朗,建议签其他公司保底!11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务