题目描述
给你一个只包含字符 'a'
,'b'
和 'c'
的字符串 s
,你可以执行下面这个操作(5 个步骤)任意次:
- 选择字符串
s
一个 非空 的前缀,这个前缀的所有字符都相同。
- 选择字符串
s
一个 非空 的后缀,这个后缀的所有字符都相同。
- 前缀和后缀在字符串中任意位置都不能有交集。
- 前缀和后缀包含的所有字符都要相同。
- 同时删除前缀和后缀。
请你返回对字符串 s
执行上面操作任意次以后(可能 0 次),能得到的 最短长度 。
示例 1:
输入:s = "ca"
输出:2
解释:你没法删除任何一个字符,所以字符串长度仍然保持不变。
示例 2:
输入:s = "cabaabac"
输出:0
解释:最优操作序列为:
- 选择前缀 "c" 和后缀 "c" 并删除它们,得到 s = "abaaba" 。
- 选择前缀 "a" 和后缀 "a" 并删除它们,得到 s = "baab" 。
- 选择前缀 "b" 和后缀 "b" 并删除它们,得到 s = "aa" 。
- 选择前缀 "a" 和后缀 "a" 并删除它们,得到 s = "" 。
示例 3:
输入:s = "aabccabba"
输出:3
解释:最优操作序列为:
- 选择前缀 "aa" 和后缀 "a" 并删除它们,得到 s = "bccabb" 。
- 选择前缀 "b" 和后缀 "bb" 并删除它们,得到 s = "cca" 。
提示:
1 <= s.length <= 105
s
只包含字符 'a'
,'b'
和 'c'
。
解法
方法一:双指针
我们定义两个指针 $i$ 和 $j$ 分别指向字符串 $s$ 的头部和尾部,然后向中间移动,直到 $i$ 和 $j$ 指向的字符不相等,此时 $\max(0, j - i + 1)$ 即为答案。
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
| class Solution:
def minimumLength(self, s: str) -> int:
i, j = 0, len(s) - 1
while i < j and s[i] == s[j]:
while i + 1 < j and s[i] == s[i + 1]:
i += 1
while i < j - 1 and s[j - 1] == s[j]:
j -= 1
i, j = i + 1, j - 1
return max(0, j - i + 1)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | class Solution {
public int minimumLength(String s) {
int i = 0, j = s.length() - 1;
while (i < j && s.charAt(i) == s.charAt(j)) {
while (i + 1 < j && s.charAt(i) == s.charAt(i + 1)) {
++i;
}
while (i < j - 1 && s.charAt(j) == s.charAt(j - 1)) {
--j;
}
++i;
--j;
}
return Math.max(0, j - i + 1);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | class Solution {
public:
int minimumLength(string s) {
int i = 0, j = s.size() - 1;
while (i < j && s[i] == s[j]) {
while (i + 1 < j && s[i] == s[i + 1]) {
++i;
}
while (i < j - 1 && s[j] == s[j - 1]) {
--j;
}
++i;
--j;
}
return max(0, j - i + 1);
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13 | func minimumLength(s string) int {
i, j := 0, len(s)-1
for i < j && s[i] == s[j] {
for i+1 < j && s[i] == s[i+1] {
i++
}
for i < j-1 && s[j] == s[j-1] {
j--
}
i, j = i+1, j-1
}
return max(0, j-i+1)
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | function minimumLength(s: string): number {
let i = 0;
let j = s.length - 1;
while (i < j && s[i] === s[j]) {
while (i + 1 < j && s[i + 1] === s[i]) {
++i;
}
while (i < j - 1 && s[j - 1] === s[j]) {
--j;
}
++i;
--j;
}
return Math.max(0, j - i + 1);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | impl Solution {
pub fn minimum_length(s: String) -> i32 {
let s = s.as_bytes();
let n = s.len();
let mut start = 0;
let mut end = n - 1;
while start < end && s[start] == s[end] {
while start + 1 < end && s[start] == s[start + 1] {
start += 1;
}
while start < end - 1 && s[end] == s[end - 1] {
end -= 1;
}
start += 1;
end -= 1;
}
(0).max(end - start + 1) as i32
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | int minimumLength(char* s) {
int n = strlen(s);
int start = 0;
int end = n - 1;
while (start < end && s[start] == s[end]) {
while (start + 1 < end && s[start] == s[start + 1]) {
start++;
}
while (start < end - 1 && s[end] == s[end - 1]) {
end--;
}
start++;
end--;
}
if (start > end) {
return 0;
}
return end - start + 1;
}
|