解题过程

:::info 题目链接
给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和
image.png :::

  1. /**
  2. * @link https://leetcode.cn/problems/pascals-triangle-ii/
  3. * @title 119. 杨辉三角 II
  4. * @description 给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。
  5. * 在「杨辉三角」中,每个数是它左上方和右上方的数的和
  6. * @param {number} rowIndex
  7. * @return {number[]}
  8. */
  9. // 解法一:
  10. // 思路:最简单的思路就是根据做过的118题的代码改一下,最终数组返回最后一个元素就可以了,注意之前参数是行数,现在是索引行,也就是相对之前遍历一维数组时临界值要+1
  11. // var getRow = function (rowIndex) {
  12. // const resultNums = []
  13. // for (let i = 0; i <= rowIndex; i++) {
  14. // const nums = []
  15. // for (let j = 0; j <= i; j++) {
  16. // // 获取上一行的值
  17. // const preNums = i === 0 ? [] : resultNums[i - 1]
  18. // // 当前元素索引值与上一行数组元素索引值关系相加得出
  19. // const pre = j - 1 >= 0 ? preNums[j - 1] : 0
  20. // const cur = j < preNums.length ? preNums[j] : 0
  21. // const currNum = pre === 0 && cur === 0 ? 1 : pre + cur
  22. // nums.push(currNum)
  23. // }
  24. // resultNums.push(nums)
  25. // }
  26. // return resultNums.pop()
  27. // }
  28. // 解法二:
  29. // 思路:递归方式,可以通过计算当前值为计算上一行的值推算出来进行累加,其实就是通过改上面的代码从for循环遍历改为递归
  30. // 缺点:像斐波那契数列,数值越大计算时间越久,官方测试用例rowIndex=24的时候就已经超出最大时间限制了
  31. // 所以该方法虽然可行,但并不是最优解,还可以再优化
  32. // 输入值24已经超出时间限制了
  33. // var getRow = function (rowIndex) {
  34. // const nums = []
  35. // const calc = (row, index) => {
  36. // console.log('row', row, index)
  37. // if (row === 0) {
  38. // return index < 0 || index > 0 ? 0 : 1
  39. // } else {
  40. // return calc(row - 1, index - 1) + calc(row - 1, index)
  41. // }
  42. // }
  43. // for (let i = 0; i <= rowIndex; i++) {
  44. // const j = calc(rowIndex, i)
  45. // console.log('j', j)
  46. // nums.push(j)
  47. // }
  48. // return nums
  49. // }
  50. // 优化递归版
  51. // 输入值11已经超出时间限制了
  52. // var getRow = function (rowIndex) {
  53. // const calc = (row, index) => {
  54. // const nums = []
  55. // // 当前行开头为1
  56. // nums.push(1)
  57. // if (row === 0) { return nums }
  58. // if (row > 1) {
  59. // for (let i = 1; i <= row - 1; i++) {
  60. // const j = calc(row - 1)[i - 1] + calc(row - 1)[i]
  61. // nums.push(j)
  62. // }
  63. // }
  64. // // 当前行结尾为1
  65. // nums.push(1)
  66. // return nums
  67. // }
  68. // return calc(rowIndex)
  69. // }
  70. // 解法三:
  71. // 思路:网上看到很不错的解题方案,其实就是我上面想破天也没想到的递归数组版
  72. var getRow = function (rowIndex) {
  73. const res = []
  74. for(let i = 1; i <= rowIndex + 1; i++) {
  75. // 当前行数的数组元素初始值都为1
  76. res[i - 1] = 1
  77. // 重置数组首尾之外元素位置的值
  78. for (let j = i - 2; j > 0; j--) {
  79. // 这一步理解起来确实有一定的难度,但也很巧妙利用当前值与上一轮计算的值关系
  80. res[j] = res[j - 1] + res[j]
  81. }
  82. }
  83. return res
  84. }
  85. const result = getRow(3)
  86. // const result = getRow(0)
  87. // const result = getRow(1)
  88. // const result = getRow(10)
  89. // const result = getRow(20)
  90. console.log(result)

解题感受

跟昨天做的118题一样的题目,只不过换了返回值,直接根据昨天的改就很简单做出来,尝试了其他解法,首先想到了递归,但是递归写的两版跟斐波那契数列一样,导致传参数值大的时候执行时间很长,不算好,理解思路即可,第三种解法是参考别人题解的,感觉还不错的解题思路,就是我一直在想的数组递归法,但是时间有限下没想出来,挺不错的解题思路,简单

参考题解

https://leetcode.cn/problems/pascals-triangle-ii/solution/javascriptban-jie-ti-si-lu-by-ityou-o-4jqr/