面试题 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; } }
答案思路是两边比较,代码较多,不手打了,贴个图吧。

------------------------------------------------
Felix原创,转载请注明出处,感谢博客园!
posted on 2013-11-27 18:26 Felix Fang 阅读(136) 评论(0) 收藏 举报
浙公网安备 33010602011771号