力扣【动态规划专题】👊 1646. 获取生成数组中的最大值

104 阅读1分钟

theme: hydrogen

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 12 天,点击查看活动详情

题目链接

1646. 获取生成数组中的最大值 - 力扣(LeetCode) (leetcode-cn.com)

题目描述

给你一个整数 n 。按下述规则生成一个长度为 n + 1 的数组 nums :

nums[0] = 0
nums[1] = 12 <= 2 * i <= n 时,nums[2 * i] = nums[i]
当 2 <= 2 * i + 1 <= n 时,nums[2 * i + 1] = nums[i] + nums[i + 1]

返回生成数组 nums 中的 最大 值。

测试用例

示例 1:

输入:n = 7
输出:3
解释:根据规则:
  nums[0] = 0
  nums[1] = 1
  nums[(1 * 2) = 2] = nums[1] = 1
  nums[(1 * 2) + 1 = 3] = nums[1] + nums[2] = 1 + 1 = 2
  nums[(2 * 2) = 4] = nums[2] = 1
  nums[(2 * 2) + 1 = 5] = nums[2] + nums[3] = 1 + 2 = 3
  nums[(3 * 2) = 6] = nums[3] = 2
  nums[(3 * 2) + 1 = 7] = nums[3] + nums[4] = 2 + 1 = 3
因此,nums = [0,1,1,2,1,3,2,3],最大值 3

限制

0 <= n <= 100

题目分析

阅读题目的生成规则,发现下标为 nums[2i] 的值,等于 nums[i],即所有的下标为偶数的值,都为其下标除 2 后对应下标的值;nums[2i + 1] = nums[i] + nums[i+1] 则可以理解为下标为奇数的的值,为下标拆分后 i, i+1 两个对应的

如果我们从 n 开始,按题目的规则去求出每个下标的值,中间会涉及到大量的重复计算,我们可以通过查临时表的方式,去优化掉重复的计算

这里分享另一种解法:直接从下标 0 开始,一路计算到 n 对应的值

已知 nums[0]=0, nums[1]=1,那么,当 i=1 时,我们可以计算出 nums[2], nums[3] 的值;当 i=2 的时候,可以计算出 nums[4], nums[5] 的值;以此类推,当 i=n/2 的时候,nums[n], nums[n+1] 的值也就出来了

考虑到 n 为奇数的情况,我们直接对 i=n/2 向上取整,并额外 +1,最后算出的数组值,截取到下标为 n 的位置即可

最后比较拿到数组中的最大值,完事!

代码实现

var getMaximumGenerated = function(n) {
    let mid = Math.floor(n / 2) + 1;
    let arr = [0, 1];
    for (let i = 1; i < mid; i++) {
        arr[i * 2] = arr[i];
        arr[i * 2 + 1] = arr[i] + arr[i + 1];
    }
    return arr.slice(0, n + 1).reduce((a, b) => Math.max(a, b), 0);
};

image.png