趣题一则:寻找那扇门
2012-04-10 23:51 Anders Cui 阅读(2427) 评论(1) 编辑 收藏 举报现在出现在你面前的是一堵朝两个方向无限延伸的墙。墙上有一扇门,但你并不确定门离你有多远,也不知道门位于哪个方向(左边或是右边)。你只有在走到门面前才能看到它。假设从当前位置到门要走n步(n大小未知),那么怎样走O(n)步就能找到那扇门?
分析
这道题让人“左右为难”,因为不确定如何才能走到尽快确定方向和位置。首先想到在错误的方向上走得越远,就意味着离正确的位置越远,因此较为保险的方法是,第一步向右走,看看有没有门;第二步——为了防止在错误的方向上渐行渐远——向左走,走两步,这样就可以确定在最初位置的一步范围内有没有门了。
接下来,按照类似的方式左右徘徊,依次确定在最初位置的2,3,...,n有没有门了。不过,直觉上就会知道走了很多冤枉路,很可能不是O(n)了。下面来具体计算一下。
假设T(n)为按上述方法确定出左右各n步范围内是否有门所需要的步数,那么
T(1) = 2 + 1
T(2) = T(1) + 2*2 + 1
T(3) = T(2) + 2*3 + 1
...
T(n) = T(n-1) + 2*n + 1
两边相加,得T(n) = n^2 + 2*n,看来这个方法太慢了。
为了更好地分析慢的原因,我们从另一个角度来看上面的方法。将寻找门的过程看作一个个回合,初始位置标记为O,第一回合向右走一步,回到O,向左走一步,回到O;第二回合向右走二步,回到O,向左走二步,回到O;。。。;第n回合向右走n步,回到O,向左走n步,回到O。这样总的步数是4*(1+2+...+n)=2(n^2+n)。每个回合仅比上一回合多一步,造成的结果就是大量的重复。但如果考虑一种极端的情况,第一回合向右走n步,回到O,向左走n步,共n步,由于不知道n的大小,这算不上是一种有效的方法,但它说明,如果我们每个回合间的跨度够大,确实有可能达到O(n)。
在常见的渐进效率类型中,比多项式明显要大的是指数级,如2^n,这里先考察这种情况。即第i回合向右走2^i步,回到O,向左走2^i步,回到O,这里0<=i<=k且2^(k-1)<n<=2^k。这样经过k个回合就可以找到门的位置,总的步数是:
可以看到,这种新的回合制是符合要求的。接下来也许可以尝试更大的跨度,如3^n或n!甚至是n*n!,这里先不讨论了。
参考:
出处:http://anderslly.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
2008-04-10 最常错的30句英语