【C++动态规划】用滚动数组节省空间复杂度

滚动数组的使用:
使用有限个位置储存元素的信息,这有限个位置相当于一个空间复杂度为O(1)的vector,每次最后一个位置放入新加入的元素,其余元素向前移动一个位置。

在每一个子问题中,dp[i]只依赖于O(1)有限个状态转移而来,那么就可以用滚动数组使空间复杂度由O(N)降为O(1)。 

 比如斐波那契数列:

如果用一维数组vector<int> dp储存状态,空间复杂度就是O(n)。因为存放了n个元素各自的斐波那契数。

dp[i]=dp[i-1]+dp[i-2],

注意到dp[i] 只依赖于dp[i-1]和dp[i-2]两个状态,而不依赖之前dp[i-3],dp[i-4]...之类的状态,换句话说,当我们处理到dp[i]时,我们无需记录dp[i-3] dp[i-4]的状态。

所以可以用两个变量p,q代表dp[i-2],dp[i-1],用r代表当前处理的dp[i],r=p+q,即相当于dp[i]=dp[i-2]+dp[i-1],然后下一次循环,让p=q,q=r,意思是数组向p的方向滚动了一位,滚动数组里原来的dp[i-2]变成dp[i-1],原来的dp[i-1]变成dp[i],r变成dp[i+1]~~

class Solution {
public:
    int fib(int n) {
        if (n < 2) {
            return n;
        }
        int p = 0, q = 0, r = 1;
        for (int i = 2; i <= n; ++i) {
            p = q; 
            q = r; 
            r = (p + q);
        }
        return r;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值