当前位置:首页 > 力扣 > LeetCode 1531题:动态规划解决字符串压缩

LeetCode 1531题:动态规划解决字符串压缩

4周前 (08-18)

LeetCode 1531题:动态规划解决字符串压缩 动态规划 字符串 力扣题解 C++ 第1张

一、题目解读

LeetCode 1531题要求给定字符串s和整数k,返回通过删除最多k个字符后,能得到的最优压缩长度。

二、解题思路

动态规划解决该问题。核心思想是将问题分解为子问题:计算前i个字符在删除j个字符后的最短压缩长度。关键在于定义状态和状态转移方程,同时考虑字符删除与保留的权衡。

三、解题步骤

1. 状态定义:创建二维dp数组dp[i][j],表示前i个字符删除j个字符后的最小压缩长度。

2. 初始化:dp[0][j]=0(前0个字符的压缩长度为0)。

3. 状态转移

    情况1(删除当前字符):若j>0,可直接继承前i-1个字符删除j-1个字符的结果,即dp[i][j] = dp[i-1][j-1]。

    情况2(保留当前字符):向前查找连续相同字符段,统计相同字符数(same)与不同字符数(diff)。当diff超过j时停止(因删除数受限),计算压缩成本(根据字符计数长度:1个字符为1,2-9个为2,10-99为3,≥100为4)。通过dp[m-1][j-diff](前m-1个字符删除j-diff个字符)转移并更新最小压缩长度。

4. 最终结果:dp[n][k]即为整个字符串在删除k个字符后的最优压缩长度。

四、代码与注释

class Solution {
public:
    int getLengthOfOptimalCompression(string s, int k) {
        int n = s.size();
        // dp[i][j]:前i个字符删除j个字符后的最小压缩长度
        vector<vector<int>> dp(n+1, vector<int>(k+1, INT_MAX/2));
        
        // 初始化:前0个字符删除j个字符的压缩长度为0
        for(int j = 0; j <= k; ++j) {
            dp[0][j] = 0;
        }
        
        for(int i = 1; i <= n; ++i) {
            for(int j = 0; j <= min(i, k); ++j) {
                // 情况1:删除当前字符
                if(j > 0) {
                    dp[i][j] = dp[i-1][j-1];
                }
                
                // 情况2:保留当前字符
                int same = 0, diff = 0;
                // 向前查找相同字符,考虑删除不同字符的情况
                for(int m = i; m >= 1; --m) {
                    if(s[m-1] == s[i-1]) {
                        same++;
                    } else {
                        diff++;
                        if(diff > j) break;
                    }
                    
                    // 更新dp值
                    int cost = 0;
                    if(same == 1) cost = 1;
                    else if(same < 10) cost = 2;
                    else if(same < 100) cost = 3;
                    else cost = 4;
                    
                    dp[i][j] = min(dp[i][j], dp[m-1][j-diff] + cost);
                }
            }
        }
        
        return dp[n][k];
    }
};

五、总结

该解法通过动态规划巧妙地将问题转化为子问题求解,时间复杂度为O(n²k),空间复杂度为O(nk)。核心难点在于状态转移时平衡删除与保留字符的策略,并通过分段计数优化压缩成本计算。适用于需要高效处理字符串压缩与删除限制的场景,为同类问题提供了经典解题思路。



原创内容 转载请注明出处

分享给朋友:

相关文章

力扣1137题:动态规划解泰波那契数 高效求解第N项的秘密

力扣1137题:动态规划解泰波那契数 高效求解第N项的秘密

一:重新解读题目泰波那契数列是一个充满数学趣味的递推序列:从第3项开始,每个数均为前三个数的和(即Tₙ₊₃ = Tₙ + Tₙ₊₁ + Tₙ₊₂)。当给定整数n时,需要高效计算出第n项的值。面对此类递...

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

题目解读给定一个不含重复元素的整数数组,我们需要构建一棵最大二叉树。构建规则是:数组中的最大值作为根节点,其左侧子数组构建左子树,右侧子数组构建右子树,然后递归地应用这个规则。这种构建方式体现了分治思...

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

题目重解我们面对一个经典背包问题的变体:给定n个物品,每个物品有重量w和价值v,背包容量为V。需要回答两个问题:1) 普通情况下能获得的最大价值;2) 必须恰好装满背包时的最大价值(若无法装满则输出0...

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

题目重解:数字三角形是一个经典的动态规划问题,给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们需要找到一条路径,使得路径上经过的数字总和最大。这个问题可以很...

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

一、题目解读2024年蓝桥杯省B组“传送阵”题目要求处理一个包含n个节点的图,节点间存在单向传输关系。每个节点i可传送至a[i]指定的节点,形成可能存在的环结构。题目需求解从任意节点出发能到达的最长路...

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

一、题目解读LeetCode 120题“三角形最小路径和”要求给定一个由数字组成的三角形,从顶部开始向下移动,每次可向左或向右移动一格,计算从顶至底的最小路径和。三角形以二维向量形式给出,每层元素数量...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。