每种字符至少取 K 个
给你一个由字符 ‘a’、‘b’、‘c’ 组成的字符串 s 和一个非负整数 k 。每分钟,你可以选择取走 s 最左侧 还是 最右侧 的那个字符。
你必须取走每种字符 至少 k 个,返回需要的 最少 分钟数;如果无法取到,则返回 -1 。
https://leetcode.cn/problems/take-k-of-each-character-from-left-and-right/description/
- 滑动窗口:保证窗口之外三种字母至少有k个。记录窗口最大值。
- 字符串中元素个数:
str.length()-str.replace(b,"").length()
或++counts[s.charAt(i) - 'a']
- 最少次数=字符串长度-滑动窗口最大值
import java.util.HashMap;
import java.util.Map;
class Solution {
public static void main(String[] args) {
String str = "aabaaaacaabc";
int k = 2;
System.out.println(takeCharacters(str, k));
}
/**
*
* @param s 待处理字符串
* @param k 字母重复次数
* @return 最少操作次数
*/
public static int takeCharacters(String s, int k) {
Map<Character, Integer> map = new HashMap<>();
map.put('a', s.length() - s.replace("a", "").length());
map.put('b', s.length() - s.replace("b", "").length());
map.put('c', s.length() - s.replace("c", "").length());
if (map.get('a') < k || map.get('b') < k || map.get('c') < k) {
return -1;
}
int maxTake = 0;
int left = 0;
for (int right = 0; right < s.length(); right++) {
map.put(s.charAt(right), map.get(s.charAt(right)) - 1);
if (map.get('a') < k || map.get('b') < k || map.get('c') < k) {
map.put(s.charAt(left), map.get(s.charAt(left)) + 1);
left++;
} else {
maxTake = Math.max(maxTake, right - left + 1);
}
}
return s.length() - maxTake;
}
}