zoukankan      html  css  js  c++  java
  • 每天一道Rust-LeetCode(2019-06-04)

    每天一道Rust-LeetCode(2019-06-04) 最长回文子串

    坚持每天一道题,刷题学习Rust.
    原题

    题目描述

    给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

    示例 1:

    输入: "babad"
    输出: "bab"
    注意: "aba" 也是一个有效答案。
    示例 2:

    输入: "cbbd"
    输出: "bb"

    解题过程

    思路:
    怎么把规模大的问题化成规模小的问题进行解决
    假设用m[i][j]表示从i到j是回文的长度
    那么只有两种情况可以扩展出回文
    m[i][j]是回文,当且仅当:

    1. m[i][j-1]是回文,并且m[i][j-1]长度是1,并且m[j-1]==m[j]
    2. m[i+1][j-1]是回文,并且m[i]==m[j]
      遍历的过程中记一个最长字符串即可.

    还有另外一种思路:
    从中间向两边扩展
    针对每个字符,不断向两边扩展以两种形式aa,a向外扩展
    第一种思路是O(n^2)复杂度
    第二种差不多也是O(n^2)复杂度,考虑到剪枝效果,会高几倍
    但是根据别人提交

    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,本项目文章所有代码都可以找到.

  • 相关阅读:
    openpose_caffe_to_rknn.py
    ncnn的完整编译过程
    We Need More Bosses CodeForces
    Yet Another Problem On a Subsequence CodeForces
    牛客 82E 无向图中的最短距离 (bitset,bfs)
    Largest Submatrix 3 CodeForces
    bzoj 4245 [ONTAK2015]OR-XOR (贪心)
    BZOJ 2836 魔法树 链剖裸题~~
    BZOJ 3083 遥远的国度 树链剖分+脑子
    Luogu P1471 方差 线段树
  • 原文地址:https://www.cnblogs.com/baizx/p/10971560.html
Copyright © 2011-2022 走看看