题目

给你一个字符串 s ,请找出满足每个字符最多出现两次的最长子字符串,并返回该

子字符串

最大 长度。

示例 1:

输入: s = “bcbbbcba”

输出: 4

解释:

以下子字符串长度为 4,并且每个字符最多出现两次:"bcbbbcba"

示例 2:

输入: s = “aaaa”

输出: 2

解释:

以下子字符串长度为 2,并且每个字符最多出现两次:"aaaa"

提示:

  • 2 <= s.length <= 100
  • s 仅由小写英文字母组成。

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int maximumLengthSubstring(String s) {
int n=s.length();
HashMap<Character,Integer> map = new HashMap<>();
int len=0;
for(int left=0,right=0;right<n;right++){
char c = s.charAt(right);
while(left<right&&map.getOrDefault(c, 0) == 2){
map.put(s.charAt(left),map.get(s.charAt(left))-1);
left++;
}
map.put(c,map.getOrDefault(c, 0)+1);
len=Math.max(len,right-left+1);
}
return len;
}
}

不太优雅,使用merge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int maximumLengthSubstring(String s) {
//滑动窗口
Map<Character, Integer> map = new HashMap<>();
int res = 0;
int left = 0;
for(int right = 0; right < s.length(); right++) {
char ch = s.charAt(right);
while(map.getOrDefault(ch, 0) >= 2) {
map.merge(s.charAt(left), -1, Integer::sum);//left对应字符个数减少1
left++;
}
map.merge(ch, 1, Integer::sum);
res = Math.max(res, right - left + 1);
}
return res;
}
}

知识点

Map 接口的 merge 方法允许你在给定的键不存在的情况下插入一个新值,或者当键已经存在时应用合并函数。

1
V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

参数

  • key: 要插入或更新的键。
  • value: 如果键不存在,则插入的默认值。
  • remappingFunction: 如果键已存在,则应用的合并函数。这个函数接受两个参数,一个是当前映射的值,另一个是默认值,并返回一个新的值。

Integer::sum 作为合并函数,这是一个引用 Integer 类的静态方法 sum 的方法引用。Integer::sum 接受两个 int 参数并返回它们的和。