LeetCode算法题-Pascal's Triangle II(Java实现)

这是悦乐书的第171次更新,第173篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第30题(顺位题号是119)。给定非负索引k,其中k≤33,返回Pascal三角形的第k个索引行。行索引从0开始。在Pascal的三角形中,每个数字是它上面两个数字的总和。例如:

输入: 2
输出: [1,2,1]

输入: 3
输出: [1,3,3,1]

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

昨天的那道题,是要求输出所有层的数据,今天这题只要求具体某一行的数据,那是不是完全可以借用昨天的代码,最后返回具体某一层即可?这种解法当然是可行的,但是题目有个提示,要求空间复杂度是O(k),其中k代表某一行。而昨天的解法,最后的空间复杂度是O(numRows^2),那能不能把空间复杂度再缩小点?答案是可以的。

我们可以先将list中的每个元素初始值设为1,然后开始循环处理。外层循环控制层数,进入内层循环,改变具体位置元素的值。我们知道第k层第j(j>=1)个元素的值是第k-1层第j-1个元素和第j个元素之和,如果按照从左至右的顺序,后面元素的值需要借助前面元素的值的时候,是已经被改变过的值,最后的结果会失真,所以我们采用从右至左的顺序设值。

注意:list.set(j, value)此方法是找到索引j所在元素,将value设值给它,不会新增元素,而add(value)是会新增元素的。

public List<Integer> getRow(int rowIndex) {
    List<Integer> list = new ArrayList<Integer>();
    for (int k = 0; k <= rowIndex; k++) {
        list.add(1);
    }
    for (int i = 1; i < rowIndex; i++) {
        for (int j = i; j > 0; j--) {
            list.set(j, list.get(j - 1) + list.get(j));
        }
    }
    return list;
}


03 第二种解法

同样是第一种解法的思路,但是我想从左至右设值怎么办?

既然想要从左至右设值,那就需要左边的数据是新的,而不是已经被计算过的新值,就需要把每次计算过的值往后移动一位,此时我们就无法在开始时就将list的初始元素值设为1,二是要在循环中添加新的元素,从而把旧的元素往后挪一位。

外层循环一方面是控制层数,另外一个方面就是每次在list的索引0位置新增元素1。只有当r等于2时,才会进入内层循环,此时list中至少有三个元素。

因为首尾元素都是1,所以内层循环的索引起始位置是1(第二位),依次往右重新设值。

public List<Integer> getRow2(int rowIndex) {
    List<Integer> list = new ArrayList<>();
    for (int r = 0; r <= rowIndex; r++) {
        list.add(0, 1);
        for (int i = 1; i < r; i++) { 
            list.set(i, list.get(i) + list.get(i + 1)); 
        }
    }
    return list;
}


04 第三种解法

我们还可以使用数组来操作此题,思路与昨天的那道题大致类似。

外层循环每次创建一个新的数组,数组长度是i+1,并且此数组的首尾元素是为1,然后开始内层循环,新数组的第j(j>=1)位元素是上一数组中的第j-1位和第j位元素之和。在结束内层循环后,还要将旧数组指向经过内层循环赋值完后的新数组。最后,将数组里面的元素遍历赋值给list。

public List<Integer> getRow3(int rowIndex) {
    List<Integer> list = new ArrayList<Integer>();
    int[] result = new int[1];
    for (int i = 0; i <= rowIndex; i++) {
        int[] next = new int[i + 1];
        next[0] = 1;
        next[i] = 1;
        for (int j = 1; j < i; j++) {
            next[j] = result[j - 1] + result[j];
        }
        result = next;
    }
    for (int in : result) {
        list.add(in);
    }
    return list;
}


05 验证与测试

针对上面三种解法,选取部分随机数字并测试不同解法耗时,代码如下:

public static void main(String[] args) {
    Easy_119_PascalTriangleII instance = new Easy_119_PascalTriangleII();
    int rowIndex = 3;
    long start = System.nanoTime();
    List<Integer> list = instance.getRow(rowIndex);
    long end = System.nanoTime();
    System.out.println("getRow---输入:"+rowIndex+" , 输出:"+list+" , 用时:"+(end-start)/1000+"微秒");
    long start2 = System.nanoTime();
    List<Integer> list2 = instance.getRow2(rowIndex);
    long end2 = System.nanoTime();
    System.out.println("getRow2---输入:"+rowIndex+" , 输出:"+list2+" , 用时:"+(end2-start2)/1000+"微秒");
    long start3 = System.nanoTime();
    List<Integer> list3 = instance.getRow3(rowIndex);
    long end3 = System.nanoTime();
    System.out.println("getRow3---输入:"+rowIndex+" , 输出:"+list3+" , 用时:"+(end3-start3)/1000+"微秒");
}

测试结果如下:

getRow---输入:10 , 输出:[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1] , 用时:73微秒
getRow2---输入:10 , 输出:[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1] , 用时:48微秒
getRow3---输入:10 , 输出:[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1] , 用时:24微秒


06 小结

解法一和解法二的思路类似,但是第二种解法稍快于解法一,第三种解法耗时最少,但是三种解法的空间复杂度都是O(k)。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

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

推荐阅读更多精彩内容

  • 算法思想贪心思想双指针排序快速选择堆排序桶排序荷兰国旗问题二分查找搜索BFSDFSBacktracking分治动态...
    第六象限阅读 3,130评论 0 0
  • 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔...
    开心的锣鼓阅读 3,325评论 0 9
  • 正常情况,一生两三万天。 生命的长度我们无法掌握,但是宽度却是可以任由自己拓展。 有的人,终其一生,拘于某个点,他...
    Azadzad阅读 565评论 0 0
  • 艾米莉·露易丝·芙洛格(Emilie LouiseFlöge)1874年8月生于维也纳,维也纳分离派的成员,奥地利...
    毒设计阅读 1,541评论 0 3
  • 办公大楼、政府机关、学校、监狱等特殊场所常常会面临外来访客管理的问题,由于场所内活动区域较多,访客进入场所内不能保...
    美迪索科阅读 414评论 0 0