递推算法之滚动数组思维方式

概述

在算法的最终结果只用到本层与上一层的结果时, 可以使用滚动数组思想。

简单的理解就是每次都使用固定的几个存储空间达到压缩节省存储空间的作用, 主要用在递推算法中。

示例1: 爬楼梯问题

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

由题可知, 在爬上第 n 阶楼梯时,可以爬 1 个或 2 个台阶, 即爬上最后一阶台阶时,总办法数 = 最后一阶台阶是 n-1 阶与 最后一阶台阶是 n-2 阶的办法数的和, 即状态转移方程为:
f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n)=f(n-1)+f(n-2) f(n)=f(n1)+f(n2)
接下来推算边界条件,即:
f ( 1 ) = 1 , f ( 2 ) = 2 f(1)=1, f(2)=2 f(1)=1,f(2)=2
即最后的代码为:

public int climbStairs(int n) {
    if (n==1) {
        return 1;
    }
    if (n==2) {
        return 2;
    }
    return climbStairs(n-1)+climbStairs(n-2);
}

这种做法的好处就是比较直观,但是方法的时间复杂度为 O ( 2 n ) O(2^{n}) O(2n)
所以这里可以用到滚动数组的思想来进行优化:

public int climbStairs(int n) {
    int left = 0, right = 0, sum = 0;
    for (int i = 1;i<=n;i++) {
        left = right;
        right = sum;
        sum = left + right;
    }
    return sum;
}

这样做的时间复杂度就降到了 O ( n ) O(n) O(n)

示例2: 最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

由题可知, 第 n 个元素的结果与第 n-1 个元素的结果以及第 n 个元素的大小有关系, 即:
f ( n ) = M a x ( f ( n − 1 ) + n u m s [ n ] , n u m s [ n ] ) f(n) = Max(f(n-1)+nums[n], nums[n]) f(n)=Max(f(n1)+nums[n],nums[n])
所以, 问题的解法即遍历数组中所有元素的并求出这些元素对应结果的最大值即可:

public int maxSubArray(int[] nums) {
    int prev = 0;
    int max = nums[0];
    for (int i:nums) {
        prev = Math.max(prev+i, i);
        max = Math.max(prev, max);
    }
    return max;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值