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

旋转数组的最小数字

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];
    }
全部评论

相关推荐

07-07 11:33
江南大学 Java
已经在暑假实习了&nbsp;,没有明确说有hc,纠结实习到八月份会不会有点影响秋招毕竟感觉今年好多提前批
程序员小白条:92的话准备提前批,其他没必要,没面试机会的,而且你要准备充分,尤其八股和算法题
点赞 评论 收藏
分享
06-15 20:57
已编辑
门头沟学院 Java
CARLJOSEPH...:年轻人有傲气很正常,但是建议工作前洗净傲气。 说实在的,什么奖学金什么奖项的都很一般。尊重你的老师,在有时间的时候去上课,真遇到走不开的事,请态度端正地向你的老师说明情况,请求请假。我相信任何一个有师德的老师都会允许的(我的老师就是这样)。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务