精華區beta Marginalman 關於我們 聯絡資訊
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') } } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.32.48.170 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Marginalman/M.1748514924.A.D2E.html ※ 編輯: yam276 (114.32.48.170 臺灣), 05/29/2025 18:41:40