[閒聊] 每日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