• 【LeetCode】312.戳气球


    题目

    有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

    现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1 和 i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1或 i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。

    求所能获得硬币的最大数量。

    示例 1:

    输入:nums = [3,1,5,8]
    输出:167
    解释:
    nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
    coins =  3*1*5    +   3*5*8   +  1*3*8  + 1*8*1 = 167

    示例 2:

    输入:nums = [1,5]
    输出:10
    

    提示:

    • n == nums.length
    • 1 <= n <= 300
    • 0 <= nums[i] <= 100

    解答

    源代码

    1. class Solution {
    2. public int[][] res;
    3. public int[] val;
    4. public int maxCoins(int[] nums) {
    5. val = new int[nums.length + 2];
    6. val[0] = 1;
    7. val[nums.length + 1] = 1;
    8. for (int i = 0; i < nums.length; i++) {
    9. val[i + 1] = nums[i];
    10. }
    11. res = new int[nums.length + 2][nums.length + 2];
    12. for (int i = 0; i < nums.length + 1; i++) {
    13. Arrays.fill(res[i], -1);
    14. }
    15. return solve(0, nums.length + 1);
    16. }
    17. // 把戳气球的过程倒过来,计算将开区间(left, right)之间填满气球能得到的最多硬币数
    18. public int solve(int left, int right) {
    19. // 此时(left, right)之间无法添加气球
    20. if (left >= right - 1) {
    21. return 0;
    22. }
    23. if (res[left][right] != -1) {
    24. return res[left][right];
    25. }
    26. for (int i = left + 1; i < right; i++) {
    27. int sum = val[left] * val[i] * val[right];
    28. sum += solve(left, i) + solve(i, right);
    29. res[left][right] = Math.max(res[left][right], sum);
    30. }
    31. return res[left][right];
    32. }
    33. }

    总结

    每戳一个气球,会使本不相邻的两个气球变得相邻,所以导致后续难以处理。所以我们换个思路,把戳气球的过程倒过来看,变成每次插进一个气球,插进第一个气球时,我们肯定知道它的两边是数字为1的气球(超出数组边界),然后这个气球的左右两边进行递归,也分别当作插进左边和右边的第一个气球。这样以来,每次添加气球时,气球两边的数字就都能够确定了。

    在每次递归时,因为当前区间内可以添加气球的位置可能不止一个,那么就需要不断对比得到能获得最大硬币数的一个。

  • 相关阅读:
    Linux知识【克隆虚拟机&配置动静态ip】
    Linux ARM平台开发系列讲解(CAN) 2.14.2 CAN调试工具安装及其使用
    Mybatis-plus中Service和Mapper
    nodejs开发的小程序 老年人健康预警系统
    【有序充电】基于粒子群算法实现电动汽车充电动态优化策略附matlab代码
    QtWebassembly遇到的一些报错问题及解决方案
    springboot 连接西门子plc,读取对应的值,并修改到数据库
    计算机网络专项练习题
    【InfoQ】博睿数据CTO孟曦东访谈实录:可观测性技术是未来发展方向
    Mysql优化-经验分享
  • 原文地址:https://blog.csdn.net/qq_57438473/article/details/132689541