[LeetCode] Shortest Palindrome I

本文详细介绍了如何通过在给定字符串的左侧添加字符来构造最短回文串,并最终形成最优回文字符串的过程。通过两种策略实现这一目标,包括直接尝试添加字符直至形成回文以及利用KMP算法优化构造过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

相关问题1:最长回文子串

相关问题2:Minimum insertions to form a palindrome

Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation. For example: Given "aacecaaa", return "aaacecaaa". Given "abcd", return "dcbabcd".

思路1:

首先判断给出的S是不是回文,然后判断在S左边添加 1 个字符后是不是回文,然后判断在S左边添加 2 个字符后是不是回文,然后判断在S左边添加 3 个字符后是不是回文。。。在S左边添加的字符要和S末尾的字符相对应。代码如下,测试的时候会超时。

class Solution {
public:
    string shortestPalindrome(string s) {
        
        int i = s.size()-1;
        string pref = "";
        
        while(!isPalin(pref+s))
        {
            pref = pref+s[i];
            i--;
        }
        
        return pref+s;
    }
    
    bool isPalin(string str)
    {
        int i=0, j=str.size()-1;
        while(i<j)
        {
            if(str[i]!=str[j])
                return false;
            else
            {
                i++;
                j--;
            }
        }
        
        return true;
        
    }
};

思路2:

We can construct the following string and run KMP algorithm on it: (s) + (some symbol not present in s) + (reversed string)

After running KMP on that string as result we get a vector p with values of a prefix function for each character (for definition of a prefix function see KMP algorithm description). We are only interested in the last value because it shows us the largest suffix of the reversed string that matches the prefix of the original string. So basically all we left to do is to add the first k characters of the reversed string to the original string, where k is a difference between original string size and the prefix function for the last character of a constructed string.

class Solution {
public:
    string shortestPalindrome(string s) {
        string rev_s = s;
        reverse(rev_s.begin(), rev_s.end());
        string l = s + "#" + rev_s;

        vector<int> p(l.size(), 0);
        for (int i = 1; i < l.size(); i++) {
            int j = p[i - 1];
            while (j > 0 && l[i] != l[j])
                j = p[j - 1];
            p[i] = (j += l[i] == l[j]);
        }

        return rev_s.substr(0, s.size() - p[l.size() - 1]) + s;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值