zoukankan      html  css  js  c++  java
  • 算法

    采访中遇到了一些算法。下面就来介绍这个算法.

    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之间,,继续本变种二进制搜索。


    算法完成

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    《Linux shell编程中 diff与vimdif的使用》RHEL6
    《mysql数据库备份小脚本》
    《linux下sudo服务的使用》RHEL6
    《通过脚本查看哪些ip被占用》shell笔记
    linux系统环境变量.bash_profile/bashrc文件
    清空系统日志shell scripts——自学笔记
    《linux源代码包的编译安装》RHEL6
    《linux 网卡别名的添加和绑定》RHEL6
    《iptables详解 》RHEL6
    转:swagger 入门
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4791686.html
Copyright © 2011-2022 走看看