一天一算法题,二分法的妙用

今天我们来讲一个比较简单的题目,这是一个好玩的题目,希望大家可以思考一下。

原题:

有 一个队列,这个队列有n个元素,并且这个队列单调上升,现在我们进行这么一个操作,把前面若干个元素剪切下来,粘到队列后面。例如 (1,2,3,4,5,6,7 我们把前3个进行这个操作,变成4,5,6,7,1,2,3;如果是4个,变成5,6,7,1,2,3,4;如果是0个,原队列不变)。现在给一个操作后 的队列,求队列中最小的元素是多少?(用越快的算法越好)

思考:

这个题目,99%的人可以用O(n)的算法来解决。但是,这是最优的么?

我们来想一想有没有更优的解法,既然比O(n)更优,那么有可能是O(logn)。我们朝这个方向思考,我们想起来我们以前学过二分查找。我们来回想一下二分查找的特性。

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好。但使用二分查找必须满足下面条件,

  1. 必须采用顺序存储结构

2.必须按关键字大小有序排列。

这个题好像并不满足是一个有序的队列,但是至少有可能是两个有序的队列。

再进一步思考,难道我们就走投无路了么?

我们先不要慌,我们来想一想这个序列长什么样子。

一天一算法题,二分法的妙用如果我们随机截取这个中间某一段,那么有两种情况。

一天一算法题,二分法的妙用

橙色部分是一个两段上升序列,而黄色的部分是一段连续上升的序列。

我们再来进一步思考,如果是黄色的情况,最小的一定是出现在最左边的。如果是橙色的情况,那么最小的出现在中间的断层。

再继续思考,假设这段线段的索引是[l,r],那么当我们取中间的mid,当我们发现a[l] < mid 的时候,是有可能是下面的情况。

一天一算法题,二分法的妙用

或者

一天一算法题,二分法的妙用我们用findMin(l, r)来表示这两种情况。当a[i] < a[mid]的时候,[l,mid]一定是上面黄色的框,[mid + 1, r] 可能是黄色的,也可能是橙色的。

findMin(l,r) = min(a[l], find(mid + 1, r));

我们来想另外一种情况, a[i] > a[mid],那么情况如下:

一天一算法题,二分法的妙用区间[mid,r]一定是上面黄色的框框,而[l, mid-1]则是橙色的框框,最小的可能是a[mid], 或者findMin(l, mid-1)。表达式为

findMin(l,r) = min(a[mid], find(l, mid - 1));

总结:

我们发现这个题目也是可以用二分法来解决的.这是最优的做法,好友说一年面试几十个人,每次都问这个,只有两三个可以短时间内想到结果。

欢迎大家关注我的头条号,也可以关注我的微信公众号(ddpcyh),会提供算法学习资料,一起来学习算法吧。

个人资料
hadoop迷
等级:6
文章:30篇
访问:2.2w
排名: 13
推荐圈子
上一篇: 一天一算法题,将复杂问题进行分解!
下一篇:谷歌的二分面试题(一日一算法题)
猜你感兴趣的圈子:
每日一算法
标签: mid、findmin、黄色、橙色、队列、面试题
隐藏