首页 > 其他分享 >LeetCode题练习与总结:移除盒子--546

LeetCode题练习与总结:移除盒子--546

时间:2025-01-15 22:29:51浏览次数:3  
标签:盒子 递归 -- 复杂度 int boxes 546 移除 dp

一、题目描述

给出一些不同颜色的盒子 boxes ,盒子的颜色由不同的正数表示。

你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k * k 个积分。

返回 你能获得的最大积分和 。

示例 1:

输入:boxes = [1,3,2,2,2,3,4,3,1]
输出:23
解释:
[1, 3, 2, 2, 2, 3, 4, 3, 1] 
----> [1, 3, 3, 4, 3, 1] (3*3=9 分) 
----> [1, 3, 3, 3, 1] (1*1=1 分) 
----> [1, 1] (3*3=9 分) 
----> [] (2*2=4 分)

示例 2:

输入:boxes = [1,1,1]
输出:9

示例 3:

输入:boxes = [1]
输出:1

提示:

  • 1 <= boxes.length <= 100
  • 1 <= boxes[i] <= 100

二、解题思路

  • 定义状态:我们使用三维数组 dp[l][r][k] 来表示从 boxes[l] 到 boxes[r] 的区间,其中 boxes[r] 后面有 k 个与 boxes[r] 相同颜色的盒子时,可以得到的最大积分。

  • 状态转移:对于每个状态 dp[l][r][k],我们需要考虑以下几种情况:

    • 从 r 开始向左找到第一个与 boxes[r] 颜色不同的盒子 p,那么 dp[l][r][k] 可以通过移除 boxes[p+1] 到 boxes[r] 的盒子来计算,即 dp[l][p][0] + (k+1)*(k+1)
    • 从 r 开始向左找到第一个与 boxes[r] 颜色相同的盒子 p,则我们可以将 boxes[p+1] 到 boxes[r-1] 的区间和 boxes[r] 后面的 k 个相同颜色的盒子合并,即 dp[l][p][k+1] + dp[p+1][r-1][0]
  • 递归和记忆化:由于状态转移是递归的,我们可以使用递归函数实现,并通过三维数组 dp 来记忆化已经计算过的状态,避免重复计算。

三、具体代码

public class Solution {
    public int removeBoxes(int[] boxes) {
        int[][][] dp = new int[100][100][100];
        return dfs(boxes, dp, 0, boxes.length - 1, 0);
    }

    private int dfs(int[] boxes, int[][][] dp, int l, int r, int k) {
        if (l > r) return 0;
        if (dp[l][r][k] != 0) return dp[l][r][k];
        
        // 移除连续相同的盒子
        while (r > l && boxes[r] == boxes[r - 1]) {
            r--;
            k++;
        }
        
        // 计算初始积分
        dp[l][r][k] = dfs(boxes, dp, l, r - 1, 0) + (k + 1) * (k + 1);
        
        // 尝试合并中间的同色盒子
        for (int i = l; i < r; i++) {
            if (boxes[i] == boxes[r]) {
                dp[l][r][k] = Math.max(dp[l][r][k], dfs(boxes, dp, l, i, k + 1) + dfs(boxes, dp, i + 1, r - 1, 0));
            }
        }
        
        return dp[l][r][k];
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度

时间复杂度分析需要考虑递归函数 dfs 被调用的次数以及每次调用时的操作数量。

  • 递归调用次数

    • 对于每个状态 (l, r, k),我们需要考虑所有可能的分割点 i,其中 l <= i < r。在最坏的情况下,对于每个状态,我们需要尝试所有可能的分割点,这会有 O(r - l) 的复杂度。
    • 由于状态 (l, r, k) 是递归定义的,并且 l 和 r 的范围是从 0 到 boxes.length - 1,我们需要对每个可能的 l 和 r 组合进行递归。在最坏的情况下,这会导致 O(n^2) 的递归调用次数,其中 n 是 boxes 数组的长度。
  • 每次调用的操作数量

    • 在每次递归调用中,我们有一个循环来遍历所有可能的分割点 i,这会导致 O(r - l) 的操作。
    • 因此,每次递归调用的操作数量是 O(n)

结合上述两点,总的时间复杂度是递归调用次数乘以每次调用的操作数量,即 O(n^2) * O(n) = O(n^3)

2. 空间复杂度

空间复杂度主要取决于递归调用栈的深度和用于记忆化存储的三维数组 dp

  • 递归调用栈

    • 递归调用栈的深度在最坏情况下与递归调用的次数相同,即 O(n^2)
  • 记忆化数组 dp

    • dp 是一个三维数组,其大小为 100 x 100 x 100,因此其空间复杂度是 O(1),因为这是一个固定的常数大小,与输入数组 boxes 的长度无关。

综上所述,总的空间复杂度是递归调用栈的深度加上记忆化数组 dp 的大小,即 O(n^2) + O(1) = O(n^2)

因此,该算法的时间复杂度是 O(n^3),空间复杂度是 O(n^2)

五、总结知识点

  • 动态规划(Dynamic Programming)

    • 动态规划是一种用于求解最优化问题的算法思想,它将问题分解为相互重叠的子问题,并通过求解子问题来构建原问题的解。
  • 递归(Recursion)

    • 递归是一种编程技巧,函数直接或间接地调用自身,用于解决可以分解为更小相似问题的问题。
  • 记忆化搜索(Memoization)

    • 记忆化是一种优化技术,用于提高函数的效率,通过存储昂贵的函数调用结果,并在需要时返回缓存的结果,避免重复计算。
  • 多维数组(Multi-dimensional Array)

    • 代码中使用了一个三维数组 dp 来存储中间状态的结果,以实现记忆化。
  • 循环和条件判断

    • 代码中使用了 while 循环来处理连续相同颜色的盒子,以及 for 循环来尝试所有可能的分割点。
    • if 语句用于检查是否可以合并中间的同色盒子。
  • 状态转移方程

    • 代码中的核心是状态转移方程,它定义了如何从一个或多个已知状态推导出新的状态。
  • 数学运算

    • 代码中使用了加法、乘法和取最大值(Math.max)等基本数学运算。
  • 数组操作

    • 代码中涉及数组的索引访问和更新操作。
  • 面向对象编程(OOP)

    • 代码封装在一个 Solution 类中,这是面向对象编程的一个基本概念。
  • 递归终止条件

    • 递归函数 dfs 中有一个基础情况,即当 l > r 时返回 0,这是递归终止的条件。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

标签:盒子,递归,--,复杂度,int,boxes,546,移除,dp
From: https://blog.csdn.net/weixin_62860386/article/details/145126307

相关文章

  • 计算机毕业设计Springboot4S店管理系统设计与实现 基于Spring Boot的4S店综合管理系统
    计算机毕业设计Springboot4S店管理系统设计与实现gn093018(配套有源码程序mysql数据库论文)本套源码可以先看具体功能演示视频领取,文末有联xi可分享随着汽车行业的蓬勃发展,4S店作为汽车销售与服务的重要场所,其管理效率和质量直接关系到客户满意度和市场竞争力。传统的手工......
  • 计算机毕业设计Springboot4S店管理系统 基于Spring Boot的汽车4S店综合管理系统设计与
    计算机毕业设计Springboot4S店管理系统w6vb2gip(配套有源码程序mysql数据库论文)本套源码可以先看具体功能演示视频领取,文末有联xi可分享随着汽车行业的蓬勃发展,4S店作为汽车销售与服务的重要场所,面临着日益复杂的运营管理挑战。传统的管理方式已经难以满足现代4S店对效率......
  • Mysql--实战篇--SQL优化(查询优化器,常用的SQL优化方法,执行计划EXPLAIN,Mysql性能调优,慢
    一、查询优化1、查询优化器(QueryOptimizer)MySQL查询优化器(QueryOptimizer)是MySQL数据库管理系统中的一个关键组件,负责分析和选择最有效的执行计划来执行SQL查询。查询优化器的目标是尽可能减少查询的执行时间和资源消耗,从而提高查询性能。查询语句不同关键字(where、......
  • Mysql--实战篇--数据库设计(范式和反范式,数据表设计原则)
    一、范式和反范式在数据库设计中,范式(Normalization)和反范式(Denormalization)是两种不同的设计理念,它们分别用于优化数据库的结构以满足不同的需求。范式主要用于减少数据冗余和提高数据完整性,而反范式则通过引入冗余来优化查询性能。1、范式(Normalization)范式是一种数据库......
  • Mysql--运维篇--备份和恢复(逻辑备份,mysqldump,物理备份,热备份,温备份,冷备份,二进制文件备
    MySQL提供了多种备份方式,每种方式适用于不同的场景和需求。根据备份的粒度、速度、恢复时间和对数据库的影响,可以选择合适的备份策略。主要备份方式有三大类:逻辑备份(mysqldump),物理备份和二进制文件备份。一、逻辑备份(LogicalBackup)逻辑备份是通过导出SQL语句或表结构和......
  • 逐笔成交逐笔委托Level2高频数据下载和分析:20250115
    逐笔成交逐笔委托下载链接:https://pan.baidu.com/s/1uRCmUTFoUZShauQ0gJYFiw?pwd=f837提取码:f837--------------------Level2逐笔成交逐笔委托数据分享下载 采用Level2逐笔成交与逐笔委托的详细记录,这种毫秒级别的数据能揭露众多关键信息,如庄家意图、虚假交易,使所有......
  • Codeforces 1536B Prinzessin der Verurteilung 题解 [ 紫 ] [ 后缀自动机 ] [ 动态规
    PrinzessinderVerurteilung:最短未出现字符串的板子。思路考虑在SAM上dp,定义\(dp_i\)表示从\(i\)节点走到NULL节点所花费的最少步数。显然我们建出反图,跑DAG上dp即可。转移如下:\[dp_i=1+\min_{j=1}^{|v_i|}dp_{v_{i,j}}\]输出方案的话记录下每个dp值的先驱,最......
  • DeepSeek Artifacts:前端开发的新利器
    DeepSeekArtifacts:前端开发的新利器人工智能领域创新不断,DeepSeekV3便是其中备受瞩目的工具之一。这款轻量级模型凭借在大语言模型(LLM)排行榜上的优异表现,以及亲民的价格和卓越的性能,在人工智能社区中广受关注。然而,它的姊妹工具DeepSeekArtifacts却因截然不同的缘由引发了热......
  • 交换机如何协助实现对网络流量的审计
    本文探讨了交换机在网络流量审计中的关键作用,强调其作为数据转发节点的优势,可实现网络可见性和合规性支持。介绍了端口镜像技术和VLAN流量审计的工作原理,提供了Cisco和华为交换机的流量审计配置命令。同时,结合安全策略,如ACL和基于用户设备的策略,优化流量审计。最后,强调了日......
  • 搭建本地日中翻译服务
    下载SakuraLLM模型鉴于显存为6G,下载20241012-Qwen2.5-1.5B-v1.0模型,去https://hf-mirror.com/SakuraLLM/Sakura-1.5B-Qwen2.5-v1.0-GGUF/tree/main下载gguf文件编译llama.cpp下载llama.cpp代码包cmake-Bbuild-DGGML_CUDA=ONcmake--buildbuild--configRelease将build......