leetcode1269 动态规划

好久不写笔记。力扣周赛164的最后一题看起来很难,但是看过解答后感觉可以做出,困扰的原因在于没有想到用动态规划解决。题目思路和官方的编码方式很值得学习,在此记录。
题目链接
官方解答

用动态规划解答

对于统计方案数的问题,应该想到动态规划。移动次数与数组长度可以做为指针i,j来构建动态数组。
初始状态:f[0][0]=1
状态方程:f[i][j]=f[i-1][j-1]+f[i-1][j]+f[i-1][j+1]
备注:j-1>=0,j+1<arrLen,结果要取模
返回值:f[steps][0]
这时想到时空复杂度应该为 steps * arrLen,arrLen 过大会导致动态数组和运算时间过大。可 arrLen 若大于 steps,题目中的指针是无法到达的,因此可以将 arrLen 减小为 steps 。时空复杂度变为 steps * min(arrLen,steps)。
官方代码的风格简单明了:

class Solution {
private:
    static const int mod = 1000000007;     //提前定义模
    
public:
    int numWays(int steps, int arrLen) {
        arrLen = min(arrLen, steps + 1);
        vector<vector<int>> f(steps + 1, vector<int>(arrLen));
        f[0][0] = 1;
        for (int i = 1; i <= steps; ++i) {
            for (int j = 0; j < arrLen; ++j) {
                for (int k = -1; k <= 1; ++k) {
                    if (j - k >= 0 && j - k < arrLen) {
                        f[i][j] = (f[i][j] + f[i - 1][j - k]) % mod;
                    }
                }
            }
        }
        return f[steps][0];
    }
};

使用 vector<vector<int>> f(steps + 1, vector<int>(arrLen)); 构建数组。
理解如下: 构建一个以vector<int>为元素类型的vector容器f,f包含 (steps+1) 个 vector<int> 类型对象,每个对象都是一个新创立的vector<int>对象的拷贝,新创立的vector<int>对象默认初始化包含arrLen个0。(参考阅读)
本题也可以使用数组构建,但vector较数组有可初始化,可动态分配,包含命令等优点。

空间优化方案

通过状态方程可以看出,每一次steps的增加,动态数组都根据上一次更新得到的数值更新,上一次更新前的数值不会再被使用,因此可不必构建
steps * min(arrLen,steps) 大小的数组, 2*min(arrLen,steps) 大小已经足够。
我们可以用奇偶判断的方式不断重用两个数组 (之前小比赛学到的 i&1 的技巧)。
官方代码:

class Solution {
private:
    static const int mod = 1000000007;
    
public:
    int numWays(int steps, int arrLen) {
        arrLen = min(arrLen, steps + 1);
        vector<vector<int>> f(2, vector<int>(steps + 1));  //此处steps + 1应为arrLen。
        f[0][0] = 1;
        for (int i = 1; i <= steps; ++i) {
            fill(f[i & 1].begin(), f[i & 1].end(), 0);
            for (int j = 0; j < arrLen; ++j) {
                for (int k = -1; k <= 1; ++k) {
                    if (j - k >= 0 && j - k < arrLen) {
                        f[i & 1][j] = (f[i & 1][j] + f[(i & 1) ^ 1][j - k]) % mod;
                    }
                }
            }
        }
        return f[steps & 1][0];
    }
};

vector容器可以使用fill函数初始化数值,若使用数组则用memset。
i&1 将 i 与1 进行二进制的与或计算,将直接得到i的最低位值,正好用于数组的0,1下标。
(i&1)^1 将 i&1 得到的数值取反,对应当前数组外的另一个数组。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,320评论 0 2
  • 回溯算法 回溯法:也称为试探法,它并不考虑问题规模的大小,而是从问题的最明显的最小规模开始逐步求解出可能的答案,并...
    fredal阅读 13,621评论 0 89
  • 概念 无后效性:一旦f(n)确定,“我们如何凑出f(n)”就再也用不着了。要求出f(15),只需要知道f(14),...
    XJBT阅读 462评论 0 1
  • 大年初一的时候,我说我明天就要去衡阳,妈妈有些不开心,要让我跟着她一起等到上班再去广州,但是我还是坚持了,然后妈妈...
    赚它个十几个亿的幸福阅读 183评论 0 1
  • 6月目标计划 001坚持每天做平板支撑 坚持了几天 002阅读书籍6本 完成《不完美才美2》《为何家会伤人》《学习...
    开不败的花阅读 215评论 0 1