LC每日一题|20240529 - 2981. 找出出现至少三次的最长特殊子字符串 I
给你一个仅由小写英文字母组成的字符串
s。如果一个字符串仅由单一字符组成,那么它被称为 特殊 字符串。例如,字符串
"abc"不是特殊字符串,而字符串"ddd"、"zz"和"f"是特殊字符串。返回在
s中出现 至少三次 的 最长特殊子字符串 的长度,如果不存在出现至少三次的特殊子字符串,则返回-1。子字符串 是字符串中的一个连续 非空 字符序列。
提示:
3 <= s.length <= 50s仅由小写英文字母组成。
题目等级:Medium
解题思路
分类讨论~
首先通过滑窗扫出所有尽可能长的特殊串,并记下由每个字母组成的特殊串的长度,然后将其排序。
对于某种字符组成的特殊串,有如下几种可能。
- 只扫出来一个特殊串a,此时满足条件的特殊串长度应为
a.length - 2 - 扫出两个特殊串a, b且长度相同,此时满足条件的最长子串应为
a.length - 1 - 扫除两个以上特殊串,其中最长的a, b长度相同,第三长的特殊串为c,此时满足条件的最长子串应为
max(a.length - 1, c。length) - 扫出多个特殊串,且最长的两个串a, b满足
a.length > b.length,此时满足条件的最长子串应为max(a.length - 2, b.length) - 如果最大子串长度小于等于
0,按题意需要维护其为-1
AC代码
class Solution {
fun maximumLength(s: String): Int {
val map = HashMap<Char, ArrayList<Int>>()
var start = 0
for (i in s.indices) {
if (s[i] != s[start]) {
map[s[start]] = (map[s[start]] ?: arrayListOf()).apply { add(i - start) }
start = i
}
}
map[s[start]] = (map[s[start]] ?: arrayListOf()).apply { add(s.length - start) }
var max = -1
for (m in map) {
val len = m.value.sorted()
val a = if (len.size == 1) {
if (len[0] > 2) len[0] - 2 else -1
} else if (len.size == 2 || len[len.size - 1] != len[len.size - 2]) {
if (len[len.size - 1] < 2) -1 else Math.max(len[len.size - 1] - 2, Math.min(len[len.size - 1] - 1, len[len.size - 2]))
} else {
Math.max(len[len.size - 3], len[len.size - 1] - 1)
}
max = Math.max(max, a)
}
return max
}
}