V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hakunamatata11
V2EX  ›  推广

[leetcode/lintcode 题解] 最长回文子串 · Longest Palindromic Substring

  •  
  •   hakunamatata11 · 2020-05-21 14:02:50 +08:00 · 711 次点击
    这是一个创建于 1500 天前的主题,其中的信息可能已经有所发展或是发生改变。

    [题目描述] 给出一个字符串(假设长度最长为 1000 ),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。

    在线评测地址: https://www.lintcode.com/problem/longest-palindromic-substring/?utm_source=sc-v2ex-fks0521

    [样例] 样例 1:

    输入:"abcdzdcab"
    输出:"cdzdc"
    

    样例 2:

    输入:"aba"
    输出:"aba"
    

    [题解]

    解法一: 基于中心点枚举的算法,时间复杂度 O(n^2)

    public class Solution {
        public String longestPalindrome(String s) {
            if (s == null || s.length() == 0) {
                return "";
            }
            
            int start = 0, len = 0, longest = 0;
            for (int i = 0; i < s.length(); i++) {
                len = findLongestPalindromeFrom(s, i, i);
                if (len > longest) {
                    longest = len;
                    start = i - len / 2;
                }
                
                len = findLongestPalindromeFrom(s, i, i + 1);
                if (len > longest) {
                    longest = len;
                    start = i - len / 2 + 1;
                }
            }
            
            return s.substring(start, start + longest);
        }
        
        private int findLongestPalindromeFrom(String s, int left, int right) {
            int len = 0;
            while (left >= 0 && right < s.length()) {
                if (s.charAt(left) != s.charAt(right)) {
                    break;
                }
                len += left == right ? 1 : 2;
                left--;
                right++;
            }
            
            return len;
        }
    }
    
    

    解法二: 使用 Manancher's Algorithm,可以在 O(n) 的时间内解决问题

    public class Solution {
        public String longestPalindrome(String s) {
            if (s == null || s.length() == 0) {
                return "";
            }
            
            // abc => #a#b#c#
            String str = generateString(s);
            
            int[] palindrome = new int[str.length()];
            int mid = 0, longest = 1;
            palindrome[0] = 1;
            for (int i = 1; i < str.length(); i++) {
                int len = 1; 
                if (mid + longest > i) {
                    int mirrorOfI = mid - (i - mid);
                    len = Math.min(palindrome[mirrorOfI], mid + longest - i);
                }
                
                while (i + len < str.length() && i - len >= 0) {
                    if (str.charAt(i - len) != str.charAt(i + len)) {
                        break;
                    }
                    len++;
                }
                
                if (len > longest) {
                    longest = len;
                    mid = i;
                }
                
                palindrome[i] = len;
            }
            
            longest = longest - 1; // remove the extra #
            int start = (mid - 1) / 2 - (longest - 1) / 2;
            return s.substring(start, start + longest);
        }
        
        private String generateString(String s) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.length(); i++) {
                sb.append('#');
                sb.append(s.charAt(i));
            }
            sb.append('#');
            
            return sb.toString();
        }
    }
    

    [更多解法可参考] https://www.jiuzhang.com/solution/longest-palindromic-substring/?utm_source=sc-v2ex-fks0521

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2590 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 09:12 · PVG 17:12 · LAX 02:12 · JFK 05:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.