递归_递归与回溯

递归和回溯

递归

一般套路

1.判断当前情况是否非法,。例如,看看当前处理的情况是否越界,是否出现了不满足条件的情况。通常,这一部分代码都是写在最前面的。

2.判断是否满足结束递归的条件。

3.将问题的规模缩小,递归调用。

4.利用在小规模问题中的答案,结合当前的数据进行整合,得出最终的答案。

代码实现

function fn(n) {
    // 第一步:判断输入或者状态是否非法?
    if (input/state is invalid) {
        return;
    }

    // 第二步:判读递归是否应当结束?
    if (match condition) {
        return some value;
    }

    // 第三步:缩小问题规模
    result1 = fn(n1)
    result2 = fn(n2)
    ...

    // 第四步: 整合结果
    return combine(result1, result2)
}

回溯

一般套路

1.判断当前情况是否非法,如果非法就立即返回;

2.当前情况是否已经满足递归结束条件,如果是就将当前结果保存起来并返回;

3.当前情况下,遍历所有可能出现的情况并进行下一步的尝试;

4.递归完毕后,立即回溯,回溯的方法就是取消前一步进行的尝试。

代码实例

function fn(n) {

    // 第一步:判断输入或者状态是否非法?
    if (input/state is invalid) {
        return;
  }

    // 第二步:判读递归是否应当结束?
    if (match condition) {
        return some value;
  }

    // 遍历所有可能出现的情况
    for (all possible cases) {
  
        // 第三步: 尝试下一步的可能性
        solution.push(case)
        // 递归
        result = fn(m)

        // 第四步:回溯到上一步
        solution.pop(case)
    
    }
    
}

分析时间复杂度

递归算法的时间复杂度分析

1.迭代法
2.公式法

公式法可以说是计算递归函数复杂度最方便的工具,当递归函数的时间执行函数满足如下的关系式时,我们可以利用公式法:T(n) = a×T(n/b) + f(n)。

其中,f(n) 是每次递归完毕之后额外的计算执行时间。例如,在归并排序中,每次递归处理完两边的数组后,我们需要执行合并的操作,那么这个操作的执行时间就是 f(n)。

当参数 a、b 都确定的时候,光看递归的部分,它的时间复杂度就是:O(n^logba)。

由于时间复杂度求的是上界,通过对比递归部分的时间复杂度和 f(n) 的大小关系,得出最后的整体时间复杂度。牢记以下三种情况和相应公式:

当递归部分的执行时间 nlog(b)a 大于 f(n) 的时候,最终的时间复杂度就是 O(n^logba)。

当递归部分的执行时间 nlog(b)a 小于 f(n) 的时候,最终的时间复杂度就是 f(n)。

当递归部分的执行时间 nlog(b)a 等于 f(n) 的时候,最终的时间复杂度就是 O(n^logba)logn。


哈希判重

特点:以空间换时间的算法。

1.直接调用Java中map的API,containsKey方法,可以判断这个key在已有的map里面存在没有。
2.重新设置一个的等长的空数组
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值