算法
2015-09-08 14:53
232 查看
采访中遇到了一些算法。下面就来介绍这个算法.
1.阶梯算法
有一个n步梯。你走两步每次要么,任一步骤。问:有几个动作。
我们先列出一些动作,例如下列。
1 2 1 1 2 ..... 1 2 1
也有可能是
1 2 1 1 2 ..... 1 1 2
我们发现一个规律,事实上最后一个数字要么是1。要么是2.这个时候,我们豁然开朗。
如果f(n)表示n阶阶梯的走法,那么必然有
f(n) = f(n-1) + f(n-2)
这样,我们就得到了这个算法。
从计算机的角度,我们须要怎么计算这个n呢,事实上能够列一个n个长度的数组,把f(i)(i为1到n的随意数字)记录下来,我们就能够通过0(n)的时间复杂度得到答案了。
细心的朋友会发现。事实上这是一个数列的表达式。对了。这事实上就是斐波那契数列。详细怎么计算这个数列。百度一下吧。以下贴一个网友给的答案。
f(n) = (1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n
这时。我们就能够通过0(1)的时间复杂度去计算了。
2.查询数字
有一组有序的数字。比方1,3 5,6,8,13,18,20。从中间某一段(不知道的某一段)分开并把后面的接到前面去,比方变成13,18,20,1,3,5,6,8。如今给你一个数k,要求在这个数组中找到k所在的位置。
这个看上去非常像一个二分查找,但二分查找的基本条件是数组有序。这时候该怎么办?
第一种方法,0(n)的时间复杂度,挨个找。非常显然不是好方法。
另外一种方法,变种的二分查找。时间复杂度是o(logn)
事实上,我们应该发现这个数组第一个元素肯定比最后一个元素大,并且第一个元素和最后一个元素最中间的元素大小一定不会在前两个元素之间。
设mid = f((n-1)/2)我们记作(mid<=f(0)&&mid<=f(n-1)) || (mid>=f(0)&&mid>=f(n-1))一定成立。
对于随意的f((n-1)/2)。我们会发现下面几种情况:
第一:(mid<=f(0)&&mid<=f(n-1)) 且k <= mid。那么k肯定在0到(n-1)/2之间。继续本变种二分查找。
第二:(mid<=f(0)&&mid<=f(n-1)) 且k >= mid,那么k肯定在(n-1)/2到n-1之间,这时候,你会发现,(n-1)/2到n-1之间的数字事实上是有序数组,我们仅仅须要利用寻常的二分查找就可以。
第三:(mid>=f(0)&&mid>=f(n-1)) 且k <= mid,那么k肯定在0到(n-1)/2之间,,这时候,你会发现,0到(n-1)/2之间的数字事实上是有序数组,我们仅仅须要利用寻常的二分查找就可以。
第四:(mid>=f(0)&&mid>=f(n-1)) 且k >= mid,那么k肯定在(n-1)/2到n-1之间,,继续本变种二进制搜索。
算法完成
1.阶梯算法
有一个n步梯。你走两步每次要么,任一步骤。问:有几个动作。
我们先列出一些动作,例如下列。
1 2 1 1 2 ..... 1 2 1
也有可能是
1 2 1 1 2 ..... 1 1 2
我们发现一个规律,事实上最后一个数字要么是1。要么是2.这个时候,我们豁然开朗。
如果f(n)表示n阶阶梯的走法,那么必然有
f(n) = f(n-1) + f(n-2)
这样,我们就得到了这个算法。
从计算机的角度,我们须要怎么计算这个n呢,事实上能够列一个n个长度的数组,把f(i)(i为1到n的随意数字)记录下来,我们就能够通过0(n)的时间复杂度得到答案了。
细心的朋友会发现。事实上这是一个数列的表达式。对了。这事实上就是斐波那契数列。详细怎么计算这个数列。百度一下吧。以下贴一个网友给的答案。
f(n) = (1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n
这时。我们就能够通过0(1)的时间复杂度去计算了。
2.查询数字
有一组有序的数字。比方1,3 5,6,8,13,18,20。从中间某一段(不知道的某一段)分开并把后面的接到前面去,比方变成13,18,20,1,3,5,6,8。如今给你一个数k,要求在这个数组中找到k所在的位置。
这个看上去非常像一个二分查找,但二分查找的基本条件是数组有序。这时候该怎么办?
第一种方法,0(n)的时间复杂度,挨个找。非常显然不是好方法。
另外一种方法,变种的二分查找。时间复杂度是o(logn)
事实上,我们应该发现这个数组第一个元素肯定比最后一个元素大,并且第一个元素和最后一个元素最中间的元素大小一定不会在前两个元素之间。
设mid = f((n-1)/2)我们记作(mid<=f(0)&&mid<=f(n-1)) || (mid>=f(0)&&mid>=f(n-1))一定成立。
对于随意的f((n-1)/2)。我们会发现下面几种情况:
第一:(mid<=f(0)&&mid<=f(n-1)) 且k <= mid。那么k肯定在0到(n-1)/2之间。继续本变种二分查找。
第二:(mid<=f(0)&&mid<=f(n-1)) 且k >= mid,那么k肯定在(n-1)/2到n-1之间,这时候,你会发现,(n-1)/2到n-1之间的数字事实上是有序数组,我们仅仅须要利用寻常的二分查找就可以。
第三:(mid>=f(0)&&mid>=f(n-1)) 且k <= mid,那么k肯定在0到(n-1)/2之间,,这时候,你会发现,0到(n-1)/2之间的数字事实上是有序数组,我们仅仅须要利用寻常的二分查找就可以。
第四:(mid>=f(0)&&mid>=f(n-1)) 且k >= mid,那么k肯定在(n-1)/2到n-1之间,,继续本变种二进制搜索。
算法完成
相关文章推荐
- SQL Server 2008 中收缩数据库(DUMP,TRANSACTION,TRAN,无效,语法错误)
- 临时解决Apache服务器假死的参数配置
- python读文件
- Unity 3D 技能释放的脚本 技能冷却时间
- 加密 xmlrpc 客户端
- 探索JFinal:小试牛刀
- 数据库连接方式
- BZOJ 2818 GCD(欧拉函数)
- Nginx转发时的重复订单问题
- 一次生成gpg key的过程
- 写时拷贝
- IOS学习笔记-ios中的文件目录和XML文件
- 关于PB调用C++的DLL
- cmake vs2013示例
- android 多渠道打包的概念及方法
- 单例完整版
- hdu 4869 Task(馋)
- 行波计数器
- archivelog启动关闭与日常维护
- iOS中delegate的使用流程简介