70.爬楼梯=====动态规划====再优化

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?

第一种方案===================记忆化搜索

为了提升算法效率,我们希望所有的重叠子问题都只被计算一次。为此,我们声明一个数组 mem 来记录 每个子问题的解,并在搜索过程中将重叠子问题剪枝。
public class 爬楼梯 {
    int count=0;
    int dfs(int i,int []memory){
        if (i==1||i==2) return i;
        if (memory[i]!=-1) return memory[i];
         count=dfs(i-1,memory)+dfs(i-2,memory);
         memory[i]=count;
         return count;
    }

        //Plan One======记忆化搜索

    int climbingStairsDFSMen(int n){
        int []mem=new int[n+1];
        Arrays.fill(mem,-1);
        return dfs(n,mem);
    }


//测试==================================================================
    public static void main(String[] args) {
        爬楼梯 s=new 爬楼梯();
        System.out.println(s.climbingStairsDFSMen(6));
        System.out.println(s.climbingStairsDP(6));//dp
        System.out.println(s.climbingStairsDPComp(6));
    }

}

第二种方案===================动态规划=========时间O(n)

记忆化搜索是一种从顶至底的方法:我们从原问题(根节点)开始,递归地将较大子问题分解为较小子问题,直至解已知的最小子问题(叶节点)。之后,通过回溯逐层收集子问题的解,构建出原问题的 解。
与之相反,动态规划是一种从底至顶的方法:从最小子问题的解开始,迭代地构建更大子问题的解,直至得到原问题的解。
由于动态规划不包含回溯过程,因此只需使用循环迭代实现,无须使用递归。在以下代码中,我们初始化一个数组 dp 来存储子问题的解,它起到了与记忆化搜索中数组 mem 相同的记录作用:
//Plan Two=======动态规划
    int climbingStairsDP(int n){
        if (n==1||n==2) return n;
        int []dp=new int[n+1];
        dp[1]=1;
        dp[2]=2;
        for (int i = 3; i <= n; i++) {
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[n];
    }

第三种方案=========动态规划之空间优化============空间O(1)

由于 dp[i] 只与 dp[i−1] dp[i−2] 有关,因此我们无须使用一个数组 dp 来存储
所有子问题的解,而只需两个变量滚动前进即可。代码如下所示:
 //Plan Two Plus======动态规划的空间优化

    int climbingStairsDPComp(int n){
        if (n==1||n==2)return n;
        int a=1,b=2;
        for (int i = 3; i <=n ; i++) {
            int temp=b;
            b=a+b;
            a=temp;
        }
        return b;
    }
经过记忆化处理后,所有重叠子问题都只需计算一次,时间复杂度优化至 O(n) ,这是一个
巨大的飞跃
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值