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

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

2个月前 (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)。核心难点在于状态转移时平衡删除与保留字符的策略,并通过分段计数优化压缩成本计算。适用于需要高效处理字符串压缩与删除限制的场景,为同类问题提供了经典解题思路。



原创内容 转载请注明出处

分享给朋友:

相关文章

线性遍历+二进制 6行代码征服二进制链表转整数

线性遍历+二进制 6行代码征服二进制链表转整数

力扣1290.二进制链表转整数题目本质给定一个单链表的头节点head,链表中每个节点的值为0或1。链表表示一个‌最高有效位在前‌的二进制数字,要求将其转换为对应的十进制整数。例如链表1→0→1对应的二...

力扣1221:一次扫描解决分割平衡字符串 时间O(n)空间O(1)

力扣1221:一次扫描解决分割平衡字符串 时间O(n)空间O(1)

题目重解给定一个仅包含'L'和'R'的字符串,要求将其分割成尽可能多的子串,且每个子串中'L'和'R'的数量相等。例如输入"R...

【深度优先搜索实战】力扣547题:省份数量问题的图论解法

【深度优先搜索实战】力扣547题:省份数量问题的图论解法

题目解读‌我们面对的是一个典型的图论问题:给定一个城市的连接矩阵,需要计算其中相互连通的城市群(省份)数量。这个问题可以抽象为无向图中的连通分量计算,每个城市代表图中的一个节点,城市之间的连接关系代表...

力扣145:递归之美 轻松掌握二叉树后序遍历

力扣145:递归之美 轻松掌握二叉树后序遍历

题目解读二叉树的后序遍历是一种基础且重要的树遍历方式,其遍历顺序为:先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。这种遍历方式特别适合需要先处理子节点再处理父节点的场景,如内存释放...

牛客12576题解题全解析:动态规划+质因数分解实现跳跃问题最优解

牛客12576题解题全解析:动态规划+质因数分解实现跳跃问题最优解

一、题目解读牛客12576题是一道经典的算法题,要求给定起点N和终点M,求解从N到M的最少跳跃次数。题目考察的核心在于路径优化与动态规划思想,需结合数论中的质因数分解技巧,通过合理设计算法降低时间复杂...

NOIP 2008火柴棒等式题解(C++代码实现)  动态规划与枚举算法详解

NOIP 2008火柴棒等式题解(C++代码实现) 动态规划与枚举算法详解

一、题目解读火柴棒等式问题(NOIP 2008,洛谷P1149)要求使用给定数量的火柴棒,构造形如 A + B = C 的等式,其中A、B、C均为整数,且火柴棒总数恰好等于输入值。需统计符合条件的等式...

发表评论

访客

看不清,换一张

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