首页 区块链

LeetCode 1717:贪心算法求解删除子字符串最大得分难题

分类:区块链
字数: (6364)
阅读: (6490)
内容摘要:LeetCode 1717:贪心算法求解删除子字符串最大得分难题,

今天我们来聊聊 LeetCode 每日一题中的 1717 题,涉及到了 nice!!! 的贪心算法思想,即删除子字符串的最大得分。这道题的核心在于如何选择删除哪些子字符串以获得最大的总分,而贪心算法提供了一种高效的解决思路。遇到这种字符串匹配和删除的场景,如果数据量较大,我们也要考虑是否可以利用 KMP 算法做预处理,加快匹配速度。

问题场景重现

题目是这样的:给定一个字符串 s 和两个整数 xy。你可以执行以下操作任意次数:

  • s 中删除子字符串 "ab" 并获得 x 分。
  • s 中删除子字符串 "ba" 并获得 y 分。

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

LeetCode 1717:贪心算法求解删除子字符串最大得分难题

例如:

输入:s = "cdababab", x = 4, y = 5
输出:19
解释:
- 删除 "ba" 得到 5 分,s = "cdabab"
- 删除 "ba" 得到 5 分,s = "cdab"
- 删除 "ab" 得到 4 分,s = "cd"
总得分为 5 + 5 + 4 = 14。

底层原理深度剖析:贪心算法的选择

贪心算法的核心在于每一步都做出当前看来最优的选择,期望最终能够达到全局最优解。对于这道题,我们可以考虑两种贪心策略:

LeetCode 1717:贪心算法求解删除子字符串最大得分难题
  1. 优先删除得分更高的子字符串。
  2. 根据字符串中 ab 的数量比例决定删除顺序。

第一种策略通常是更有效的。我们可以先尝试删除得分更高的子字符串,直到无法删除为止,然后再删除得分较低的子字符串。这种策略能够保证在每一步都最大化当前得分。

在实现上,我们可以使用栈来辅助删除子字符串。具体来说,我们遍历字符串 s,如果栈顶的字符和当前字符能够组成 "ab""ba",就从栈中弹出栈顶字符,并累加相应的得分。否则,就将当前字符压入栈中。

LeetCode 1717:贪心算法求解删除子字符串最大得分难题

这种算法的时间复杂度是 O(n),其中 n 是字符串 s 的长度。空间复杂度也是 O(n),主要用于栈的存储。

具体的代码解决方案 (Java)

class Solution {
    public int maximumGain(String s, int x, int y) {
        int score = 0;
        // 优先删除得分高的子字符串
        String first = "ab", second = "ba";
        if (x < y) {
            first = "ba";
            second = "ab";
            int temp = x;
            x = y;
            y = temp;
        }
        
        StringBuilder stack = new StringBuilder();
        for (char c : s.toCharArray()) {
            stack.append(c);
            int len = stack.length();
            if (len >= 2) {
                String lastTwo = stack.substring(len - 2, len);
                if (lastTwo.equals(first)) {
                    score += x;
                    stack.delete(len - 2, len); // 删除"ab"或者"ba"
                } else if (lastTwo.equals(second)) {
                    score += y;
                    stack.delete(len - 2, len); // 删除"ab"或者"ba"
                }
            }
        }

        return score;
    }
}

这里我们优先判断 xy 的大小,保证 first 存储的是得分更高的子字符串,second 存储的是得分较低的子字符串。通过 StringBuilder 模拟栈操作,简化了代码逻辑。

LeetCode 1717:贪心算法求解删除子字符串最大得分难题

实战避坑经验总结

  1. 注意边界条件:例如,字符串 s 为空或者 xy 都为 0 的情况。
  2. 优先顺序:一定要优先删除得分高的子字符串,否则可能会得到错误的答案。
  3. 数据规模:如果字符串 s 非常长,可以考虑使用更高效的数据结构,例如使用数组模拟栈,避免频繁的字符串拷贝。同时,也要注意JVM的GC调优,避免频繁 Full GC 影响性能。如果后端服务是使用 Spring Boot 框架,要合理设置 JVM 参数。
  4. 测试用例:编写充分的测试用例,覆盖各种情况,确保代码的正确性。
  5. 避免重复计算:一些同学可能采用递归或者动态规划,但是该题使用贪心算法最佳,代码简洁高效。遇到类似问题,不要盲目套用复杂的算法。
  6. 关注并发场景:在实际的生产环境中,如果该算法作为服务的一部分,需要考虑并发请求的处理。可以使用线程池或者异步编程来提高服务的吞吐量。如果采用 Nginx 做反向代理,需要合理配置 worker_processesworker_connections,保证服务能够承受高并发的压力。同时也要监控服务器的 CPU、内存、IO 等指标,及时发现和解决性能瓶颈。

这道 nice!!! 题的解法就分享到这里,希望对大家有所帮助。祝大家刷题愉快!

LeetCode 1717:贪心算法求解删除子字符串最大得分难题

转载请注明出处: 代码旅行家

本文的链接地址: http://m.acea2.store/blog/111117.SHTML

本文最后 发布于2026-04-21 01:22:15,已经过了6天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 黄焖鸡米饭 1 天前
    学习了!最近在优化一个服务,正愁并发上不去,关于 Nginx 的并发配置和 JVM 调优的建议很有价值。
  • 格子衫青年 5 天前
    感谢分享!Java 代码简洁易懂,学到了用 StringBuilder 模拟栈的技巧。