堅持天天一道題,刷題學習Rust.
原題git
給定一個字符串 s,找到 s 中最長的迴文子串。你能夠假設 s 的最大長度爲 1000。github
示例 1:工具
輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。
示例 2:學習
輸入: "cbbd"
輸出: "bb"code
思路:
怎麼把規模大的問題化成規模小的問題進行解決
假設用m[i][j]表示從i到j是迴文的長度
那麼只有兩種狀況能夠擴展出迴文
m[i][j]是迴文,當且僅當:ci
還有另一種思路:
從中間向兩邊擴展
針對每一個字符,不斷向兩邊擴展以兩種形式aa,a向外擴展
第一種思路是O(n^2)複雜度
第二種差很少也是O(n^2)複雜度,考慮到剪枝效果,會高几倍
可是根據別人提交leetcode
struct Solution {} impl Solution { pub fn longest_palindrome(s: String) -> String { if s.len() <= 0 { return s; } let ss = s.as_bytes(); let mut m = vec![vec![0; ss.len()]; ss.len()]; // for i in 0..m.len() { // m[i] = Vec::with_capacity(s.len()); // } for i in 0..m.len() { m[i][i] = 1; //自身確定是一個迴文 } let mut longest = &ss[0..1]; //step for k in 1..s.len() { //元素下標 for i in 0..s.len() { if (i + k) < s.len() && m[i][i + k - 1] == 1 && ss[i + k - 1] == ss[i + k] { m[i][i + k] = 2; if longest.len() <= k { longest = &ss[i..(i + k + 1)]; //包含最後一位 } } else { let s = i + 1; let e = i + k - 1; if i + 1 >= m.len() || i + k >= m.len() { continue; //越界的不考慮 } if m[i + 1][i + k - 1] > 0 && ss[i] == ss[i + k] { m[i][i + k] = m[i + 1][i + k - 1] + 2; //向周邊擴展了兩位 if longest.len() <= k { longest = &ss[i..(i + k + 1)]; //包含最後一位 } } } } } String::from_utf8(Vec::from(longest)).ok().unwrap() } } #[cfg(test)] mod test { use super::*; #[test] fn test_longest_palindrome() { assert_eq!(Solution::longest_palindrome(String::from("babad")), "bab"); assert_eq!(Solution::longest_palindrome(String::from("babba")), "abba"); assert_eq!(Solution::longest_palindrome(String::from("abcdef")), "a"); assert_eq!(Solution::longest_palindrome(String::from("")), ""); assert_eq!(Solution::longest_palindrome(String::from("abbcd")), "bb"); } }
`String::from_utf8(Vec::from(longest)).ok().unwrap() `字符串之間的轉換仍是不太熟悉, 基本工具使用不夠熟練
歡迎關注個人github,本項目文章全部代碼均可以找到.字符串