[闲聊] 每日leetcode 75 - Day3 - 2

楼主: yam276 ('_')   2025-05-29 18:35:21
345. Reverse Vowels of a String
https://leetcode.com/problems/reverse-vowels-of-a-string/
题意:
简单题
把输入字串的元音顺序反转 其余不变
思路:
本来想说储存元音的字母跟位置
但后来发现太麻烦了
直接
1. 遍历第一次蒐集字母
2. 字母阵列反转
3. 遍历把字母塞回去
这样只需要纪录字母
不过中间遇到 Rust 为了优化效能使用的 Lazy Iterator 问题
本来我写
let vowels: Vec<char> = s.chars().filter(|&c| Self::is_vowel(c)).collect();
vowels.reverse();
s.chars()
.map(|c| {
if Self::is_vowel(c) {
vowels.pop().unwrap() // ← 问题在这里
} else {
c
}
})
.collect()
因为 Rust 是 Lazy Iterator 求值
只有在 .collect() .for_each() .next()
这种终结操作函数的时候才一次执行所有 closure (闭包) 的东西
而我在 closure 里面进行外部变量的借用与变动 .pop() 方法
导致编译器无法确认 borrow check
导致行为不稳定 (根据编译器而有不同结果)
像我给 leetcode 执行的时候就出现没真的改变量值的情况
所以我要改成用另一个 vowel_iter 先把反转做完
使用 .into_iter() 拿所有权与跟在使用 closure 前先 rev 完
这样不但不用分配新内存 rev 也只是改 iterator 顺序 很省效能
另外还写了一个辨识字母的 sub function
幸好 Rust 有大家一起比的 macro 可以用
Code:
impl Solution {
pub fn reverse_vowels(s: String) -> String {
let mut vowels: Vec<_> = s.chars()
.filter(|&c| Self::is_vowel(c))
.collect();
let mut vowel_iter = vowels.into_iter().rev();
s.chars()
.map(|c| {
if Self::is_vowel(c) {
vowel_iter.next().unwrap()
} else {
c
}
})
.collect()
}
fn is_vowel(c: char) -> bool {
matches!(c, 'a' | 'e' | 'i' | 'o' | 'u' | 'A' | 'E' | 'I' | 'O' | 'U')
}
}

Links booklink

Contact Us: admin [ a t ] ucptt.com