构造限制重复的字符串
难度:
标签:
题目描述
代码结果
运行时间: 87 ms, 内存: 17.0 MB
/*
* 思路:
* 1. 使用Stream对字符串s的字符进行排序,并计数。
* 2. 遍历排序后的字符,并按repeatLimit的要求构造结果字符串。
*/
import java.util.*;
import java.util.stream.Collectors;
public class Solution {
public String repeatLimitedString(String s, int repeatLimit) {
// 获取字符频率和字典序排序的列表
List<Map.Entry<Character, Long>> sortedEntries = s.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(c -> c, Collectors.counting()))
.entrySet()
.stream()
.sorted((a, b) -> b.getKey().compareTo(a.getKey()))
.collect(Collectors.toList());
StringBuilder result = new StringBuilder();
for (int i = 0; i < sortedEntries.size(); i++) {
Map.Entry<Character, Long> entry = sortedEntries.get(i);
char current = entry.getKey();
long freq = entry.getValue();
long count = Math.min(freq, repeatLimit);
for (int j = 0; j < count; j++) {
result.append(current);
}
sortedEntries.set(i, Map.entry(current, freq - count));
if (freq - count > 0) {
if (i + 1 < sortedEntries.size()) {
result.append(sortedEntries.get(i + 1).getKey());
long nextFreq = sortedEntries.get(i + 1).getValue() - 1;
if (nextFreq > 0) {
sortedEntries.set(i + 1, Map.entry(sortedEntries.get(i + 1).getKey(), nextFreq));
} else {
i++; // skip the next entry
}
i--; // reprocess the current entry
}
}
}
return result.toString();
}
}
解释
方法:
此题解采用排序和贪心策略构建字典序最大的字符串。首先,使用计数器统计字符串s中每个字符的出现次数。然后,对字符进行降序排序。通过迭代排序后的字符列表,贪心地构建结果字符串。每次尝试添加最大字母直到达到其限制repeatLimit,如果剩余数量仍较多,则尝试插入次大字母一次,以打破重复序列,再继续添加最大字母。此过程循环进行,直到无法添加更多字符为止。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在贪心选择时优先尝试添加字典序最大的字符直到达到其repeatLimit?
▷🦆
在处理只剩一个字符时,为什么选择添加该字符的最大可能重复数而不是尝试其他可能的字符组合?
▷🦆
当f指针的字符数量大于s指针的字符数量乘以repeatLimit时,为什么选择重复添加f指针的字符和s指针的字符的组合直到s用完?
▷🦆
在代码中如何处理当fc的数量小于sc的数量乘以repeatLimit时的情况,具体的逻辑是怎样的?
▷