递归

作者: 夕阳下的不回头 | 来源:发表于2018-07-02 10:28 被阅读18次

    如何设计一个高效的DSA呢? 分而治之

    不要一下解决 要分解问题成子问题 慢慢解决

    举一个很简单的例子

    时间复杂度是O(n)  其实只需要看循环结构  没有循环的地方复杂度肯定是O(1)

    空间复杂度的两种想法

    1、输入的A[] n 还有sum i

    空间复杂度是O(n)

    2、输入的A[] n 不计入  

    只有sum i

    我们更倾向于第二种

    也就是这个算法的空间复杂度是O(1)

    通常来讲 

    凡是空间复杂度的讨论都是

    除了输入本身所占的空间之外

    我们所需要的另加的用于计算所必须的空间

    上述例子给了我们一个处理问题的方法

    处理问题的方法:

    这个平凡 指的是这个问题很容易解决了

    缩减 指的是问题的规模小了 但是类型没变 

    因此可以一直这么处理下去  直到该大问题全部解决

    递归算法分析的第一个技巧 递归跟踪

    递归跟踪:

    查看复杂度的时候  递归中调用自己的那个归入下一层递归中 这一步的复杂度是O(1)不影响大局

    当前递归只关心A[n-1]这一步

    可以看到的是每一步的sum(A,n)时间复杂度都是O(1)因为只有个加法

    一共有n+1次递归  那么一共就有O(1)*(n+1)=O(n)

    上述的递归是一个前递归产生一个后递归  也叫线性递归

    为了更好的分析复杂的递归

    我们给出另外一种方法 递推方程

    间接抽象,更适用于复杂的递归模式

    如果递归

    上述是隐式表达 由递推方程和边界条件就能解出显式表达

    另外一个例子:

    另一个策略 分而治之

    所谓的递归基 就是最简单的情况  最容易解决的情况

    就像下面的区间变成一个元素 区间上限下限相等

     这就是递归基

    直到lo全部等于hi的时候才行

    查看刚才的递归 

    把递归调用本身去掉的话

    没有循环 也不包含任何隐式显式迭代

    所以要计算时间复杂度的话我们只需要把递归的个数算出来就行了

    那么问题来了  :怎么算

    从代数层面看 是列代数方程式

    但是 我们不想 或者说 不喜欢你采用这种方式

    我们从几何层面看

    每一层都是2的倍数对吧 

    关键是最后一层是多少

    最后一层是n 没错 为什么呢  因为最后一行等价于把每个元素罗列出来

    最后一个元素其实就是n  但是为了写成 等比数列的形式呃。。。也就是以2为倍数的几何级数的形式

    几何级数的形式 时间复杂度与末项同阶

    再从递归方程的角度分析

    MAX2问题 

    首先第一个方法

    最好和最坏情况比较次数都一样都是2n-3

    第二个方法  扫描一遍逐个比较

    这个方法的好处在于  最好情况确实减少了时间 但是最坏情况并没有改善

    以上两种情况都是只看了if语句  没有关心里面的时间复杂度 或者说默认了swap这个函数的复杂度是O(1)

    以上算法的最坏情况没有真正改进  接下来给出真正意义上的改进算法

    首先把整个数组划为两部分  然后分别求出这两部分的最大值和次大值

    X1L与X1R先比较  X1L胜出的话  X1L为整体最大值

    X2L再和X1R比较  确定整体次大值

    注意 这里X2R是不需要比较的

    注意代码语法 应该是使用了引用的那个语法 &x1直接在函数里修改X1L X1R X2L X2R

    自己写一写试试吧

    相关文章

      网友评论

          本文标题:递归

          本文链接:https://www.haomeiwen.com/subject/bndkuftx.html