leetcode
leetcode 2751 ~ 2800
进行操作使字符串为空

进行操作使字符串为空

难度:

标签:

题目描述

You are given a string s.

Consider performing the following operation until s becomes empty:

  • For every alphabet character from 'a' to 'z', remove the first occurrence of that character in s (if it exists).

For example, let initially s = "aabcbbca". We do the following operations:

  • Remove the underlined characters s = "aabcbbca". The resulting string is s = "abbca".
  • Remove the underlined characters s = "abbca". The resulting string is s = "ba".
  • Remove the underlined characters s = "ba". The resulting string is s = "".

Return the value of the string s right before applying the last operation. In the example above, answer is "ba".

 

Example 1:

Input: s = "aabcbbca"
Output: "ba"
Explanation: Explained in the statement.

Example 2:

Input: s = "abcd"
Output: "abcd"
Explanation: We do the following operation:
- Remove the underlined characters s = "abcd". The resulting string is s = "".
The string just before the last operation is "abcd".

 

Constraints:

  • 1 <= s.length <= 5 * 105
  • s consists only of lowercase English letters.

代码结果

运行时间: 134 ms, 内存: 18.6 MB


/*
 * 思路:
 * 1. 使用 Java Stream API 处理字符串,遍历字母 'a' 到 'z'。
 * 2. 每次找到并删除最早出现的字符。
 * 3. 使用一个 List 保存每次操作前的字符串。
 */

import java.util.*;
import java.util.stream.IntStream;

public class StreamSolution {
    public String findLastBeforeEmpty(String s) {
        List<String> history = new ArrayList<>();
        history.add(s);
        for (char c = 'a'; c <= 'z'; c++) {
            int index = IntStream.range(0, s.length()).filter(i -> s.charAt(i) == c).findFirst().orElse(-1);
            if (index != -1) {
                s = s.substring(0, index) + s.substring(index + 1);
                history.add(s);
            }
        }
        return history.size() > 1 ? history.get(history.size() - 2) : s;
    }
}

解释

方法:

这个题解似乎并不完全符合题目的要求。题目要求移除字符串中按字母表顺序出现的最早字符,直到字符串为空。但题解中的方法更像是查找并返回出现最多次的字符的最后出现位置的字符串。具体步骤如下: 1. 使用Counter计算每个字符在字符串中出现的次数。 2. 构建一个字典记录每个字符最后一次出现的位置。 3. 找到出现次数最多的字符,记录这些字符最后一次出现的索引。 4. 按索引顺序返回这些字符组成的字符串。

时间复杂度:

O(n + k log k)

空间复杂度:

O(1)

代码细节讲解

🦆
题解中的算法策略与题目的要求似乎不符,你是如何确定使用这种方法来解决问题的?
题解中的算法确实与题目要求不符。这可能是因为题解的作者误解了题目的要求或者是题解错误地被应用到了这个问题上。正确的做法应该是按照题目要求,迭代地遍历字母表,依次移除字符串中第一次出现的字符,直到字符串为空。题解中的方法更适合用于统计字符出现频率并按特定规则输出字符,这与原题的目标有本质的不同。
🦆
在题解中使用`Counter`来统计字符出现次数,这种方法在处理大字符串时效率如何?是否有更优的实现方式?
`Counter`是一个非常高效的工具,用于统计数据中元素的出现频率。它的时间复杂度通常为O(n),其中n是字符串的长度。对于大型数据集,这通常是可接受的。然而,如果我们知道字符集是有限的(例如ASCII字符),则可以使用固定大小的数组或字典来手动计数,这可能在某些情况下稍微提高效率。但总体来说,`Counter`已足够优化,适用于大多数情况。
🦆
题解中使用了排序操作`sorted(last[ch] for ch, c in cnt.items() if c == mn)`,这个排序的时间复杂度是多少?是否对算法总体性能有重大影响?
这个排序操作的时间复杂度是O(k log k),其中k是出现次数最多的字符数量。在最坏的情况下,如果每个字符的出现次数都相同,k可以达到字符集的大小,可能接近或等于n。通常,排序操作可能会在性能上有所影响,特别是当k接近n时。然而,这是否有重大影响取决于具体情况,包括数据的大小和分布。如果k相对较小,则这种影响可能不大。

相关问题