面试题 8,旋转数组的最小数字

毫无疑问,从头到尾遍历一遍O(N) 可以解决问题,但这样我们没有利用到旋转数组的特性。

我的思路和书上的思路略有区别:

用形状来表示递增数组可能更加直观,如下图所示,取旋转后的数组的中点值Pmid,和数组尾值Pend比较。在case1中,Pmid小于Pend,由此我们可以确定这一部分还是完整的递增数组,因此旋转节点应该在Pmid之前;在case2中,Pmid大于Pend(因为Pmid大于当前数组头部值,而当前数组头部值大于Pend),由此可以确定Pmid到Pend段肯定经过了旋转。

接下来就可以缩小范围,在这个小范围中,可以重复利用这个算法。

那么若是Pmid==Pend呢?那就得使用O(N)的方法遍历了。

 自己的代码:

template<typename T> T findSmallest(T *list, const int start, const int end){
    if(start > end){
        throw std::Exception("illegal input of start and end place");
    }
    if(start == end){
        return list[start];
    }
    T mid = (start + end)/2;
    if(list[mid] < list[end]){
        return findSmallest(list, start, mid);
    }else if(list[mid] > list[end]){
        return findSmallest(list, mid + 1, end);
    }else{
        T smallest = list[start];
        for(int i = start;i < end+1;i++){
            if(smallest > start[i]){
                smallest = start[i];
            }
        }
        return smallest;
    }
}

答案思路是两边比较,代码较多,不手打了,贴个图吧。

 

 

posted on 2013-11-27 18:26  Felix Fang  阅读(136)  评论(0)    收藏  举报

导航