4.9 KiB
4.9 KiB
- 3137. K 周期字符串需要的最少操作次数
- 按照 k 长度进行字符串分割
- 把分割的子串做为hashmap的key,计算不同的key计数
- 用总的子串数 - 最多计数的子串数
411 周赛
- 100402. 统计满足 K 约束的子字符串数量 I - 力扣(LeetCode)
-
使用暴力dp
计算 i-j 的 ‘0’ 和 ‘1’ 的数量,通过计算 i-j 之前的子串数量,再求和。最后得到的答案
-
使用滑动窗口
impl Solution { pub fn count_k_constraint_substrings(s: String, k: i32) -> i32 { let mut ans: i32 = 0; let mut left = 0; let mut cnt = [0; 2]; let chars = s.chars().collect::<Vec<char>>(); for (right, ch) in chars.iter().enumerate() { // 计算当前窗口的 '0' '1' 的数量 cnt[ch.to_digit(10).unwrap() as usize] += 1; // 如果窗口内的 '0' '1' 数量不满足条件,则通过 left+=1;移动窗口 while cnt[0] > k && cnt[1] > k { cnt[chars[left].to_digit(10).unwrap() as usize] -= 1; left += 1; } // 把窗口长度加到结果里面,窗口内的符合条件的子串,会被其他窗口添加进去 ans += (right - left + 1) as i32; } return ans; } }
-
3306. 元音辅音字符串计数 II - 力扣(LeetCode)
use std::collections::HashMap;
impl Solution {
pub fn count_of_substrings(word: String, k: i32) -> i64 {
let len = word.len();
let word_arr = word.chars().collect::<Vec<char>>();
let mut vowel_map: HashMap<char, i32> = HashMap::new();
let mut k_cnt = 0;
fn is_vowel(c: &char) -> bool {
"aeiou".contains(*c)
}
let mut last_next = len;
let mut cache = vec![0; len];
for i in (0..len).rev() {
cache[i] = last_next;
if !is_vowel(&word_arr[i]) {
last_next = i;
}
}
let mut left = 0;
let mut ans = 0;
for right in 0..len {
if is_vowel(&word_arr[right]) {
let e = vowel_map.entry(word_arr[right]).or_insert(0);
*e += 1;
} else {
k_cnt += 1;
}
let val = cache[right] - right;
while (left <= right && k_cnt > k) || (vowel_map.len() == 5 && k_cnt == k) {
if vowel_map.len() == 5 && k_cnt == k {
ans += val as i64;
}
let l_ch = &word_arr[left];
if is_vowel(l_ch) {
let e = vowel_map.entry(*l_ch).or_insert(0);
if *e == 1 { vowel_map.remove(&l_ch); } else { *e -= 1; }
} else {
k_cnt -= 1;
}
left += 1;
}
}
ans
}
}
第二种,看的大佬的题解:把计算k个辅音字母数,改成至少 k 个辅音字母数,最后可以通过,fn(k) - f(k+1) 计算的到复合预期的子字符串的总数, 代码如下:
use std::collections::HashMap;
impl Solution {
pub fn count_of_substrings(word: String, k: i32) -> i64 {
fn cal(word: &Vec<char>, k: i32) -> i64 {
let len = word.len();
let mut vowel_map: HashMap<&char, i32> = HashMap::new();
let mut k_cnt = 0;
fn is_vowel(c: &char) -> bool {
"aeiou".contains(*c)
}
let mut left = 0;
let mut ans = 0;
for (i, ch) in word.iter().enumerate() {
if is_vowel(ch) {
let e = vowel_map.entry(ch).or_insert(0);
*e += 1;
} else {
k_cnt += 1;
}
while vowel_map.len() == 5 && k_cnt >= k {
let l_ch = &word[left];
if is_vowel(&l_ch) {
let e = vowel_map.entry(l_ch).or_insert(0);
if *e == 1 { vowel_map.remove(&l_ch); } else { *e -= 1; }
} else {
k_cnt -= 1;
}
left += 1;
}
ans += left as i64;
}
ans
}
let char_arr = word.chars().collect::<Vec<char>>();
cal(&char_arr, k) - cal(&char_arr, k+1)
}
}