• [LeetCode] Shortest Palindrome


    https://leetcode.com/problems/shortest-palindrome/?tab=Description

    思路1:Brute Force

    问题的核心就在于如何快速找到以所给字符串第一个字符开始的最长回文串。一种暴力枚举的方案是,从后往前枚举可能的回文串的终点,检测是否发现回文串,是的话即可结束枚举。极端情况是,以第一个字符开始的最长回文串就是它本身,这种情况下需要扫描整个字符串(检测是否回文需要O(n))。

    Time complexity: O(n^2)
    Space complexity: O(1)

    class Solution {
    public:
        string shortestPalindrome(string s) {
            if (s.empty()) return "";
            
            int max_len = 1;
            for (int j = s.size() - 1; j > 0; --j) {
                // determine if s[0...j] is palindrome
                bool sign = true;
                for (int l = 0, r = j; l < r; l++, r--) {
                    if (s[l] != s[r]) {
                        sign = false; break;
                    }
                }
                if (sign) {
                    max_len = j + 1; break;
                }
            }
            
            string addstr = s.substr(max_len, s.size() - max_len);
            reverse(addstr.begin(), addstr.end());
            return addstr + s;
        }
    };
    

    ps. 这种最暴力的方法可以AC,leetcode 276ms

    思路2:Manacher's algorithm

    著名的Manacher算法可以在线性时间内计算出一个字符串中所有以某字符为中心的最长回文串,具体的算法细节可以参见 (http://acm.uestc.edu.cn/bbs/read.php?tid=3258) 。对于本问题,须要找的是以某字符开始的最长回文串,在算法运行的时候每确定一个回文串之后判断一下其左边界是否对应该字符,是的话更新一下回文串长度即可。

    Time complexity: O(n)
    Space complexity: O(n)

    class Solution {
    public:
        string shortestPalindrome(string s) {
            if (s.empty()) return "";
            
            int max_len = 1;
            
            // Manacher's algorithm
            string str = "$#";
            for (char c : s) {
                str.push_back(c);
                str.push_back('#');
            }
            int mx = 0, id;
            vector<int> p(str.size(), 0);
            for (int i = 1; i < str.size(); ++i) {
                if (mx > i) 
                    p[i] = min(p[2*id-i], mx-i);
                else
                    p[i] = 1;
                for (; str[i+p[i]] == str[i-p[i]]; p[i]++);
                if (p[i] + i > mx) {
                    mx = p[i] + i;
                    id = i;
                }
                // update max_len start from the frist char
                if (i-p[i]+1 == 1) max_len = p[i] - 1;
            }
            
            string addstr = s.substr(max_len, s.size() - max_len);
            reverse(addstr.begin(), addstr.end());
            return addstr + s;
        }
    };
    

    ps. 该算法的性能明显比前一种强多了,leetcode 6ms

  • 相关阅读:
    sed命令详解 皇星客栈
    FD_set FD_zero 皇星客栈
    linux tr命令详解 皇星客栈
    解决中文乱码问题(Ubuntu) 皇星客栈
    FIFO深度 皇星客栈
    输入阻抗 皇星客栈
    APROM Data Flash LDROM 皇星客栈
    kubernetes 1.21 部署业务
    kubernetes 1.21部署 cephcsi rbd
    kubernetes 1.21 部署 dashboard
  • 原文地址:https://www.cnblogs.com/ilovezyg/p/6477496.html
Copyright © 2020-2023  润新知