LeetCode

题目

URL:https://leetcode.com/problems/longest-palindromic-substring

解法

一、循环搜索

对于每一个字符,往后搜索,遇到相同字符,开始判断是否回文串,若是回文串则与当前最长回文串的长度比较,若更长,则更新最长回文串。

显然是三层循环:第一层确定回文串起始位置,第二层确定回文串终止位置,第三层判断是否是回文串。

代码也比较简洁,可是循环太多。

    public String longestPalindrome(String s) {
        String maxString = null;
        int maxLength = 0;
        for (int i = 0, left = i; i < s.length(); i++) {
            for (int j = i, right = j; j < s.length(); j++, left = i, right = j) {
                while (left < s.length() && right >= 0 && left < right && s.charAt(left) == s.charAt(right)) {
                    left++;
                    right--;
                }
                if (left >= right && j - i + 1 > maxLength) {
                    maxLength = j - i + 1;
                    maxString = s.substring(i, j + 1);
                }
            }
        }
        return maxString;
    }

循环搜索,时间复杂度O(n3),运行时间约为 TLE

二、向外查找

对于每一个字符,假定它(回文串长度为奇数)或者它和它的右面字符(回文串长度为偶数)是回文串,那么我们只需要向外扩张,直到它不是回文串。

该算法其奥妙在于假定和向外扩张,而不是盲目搜索。

    private int start;
    private int maxLength;

    public String longestPalindrome(String s) {
        if (s.length() == 0) return "";
        for (int i = 0; i < s.length(); i++) {
            findPalindrome(s, i, i);
            findPalindrome(s, i, i + 1);
        }
        return s.substring(start, start + maxLength);
    }

    private void findPalindrome(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        if (right - left - 1 > maxLength) {
            start = left + 1;
            maxLength = right - left - 1;
        }
    }

向外查找,时间复杂度O(n2),运行时间约为 17 ms

总结

有的时候思路要放开,不要太计算机思维(搜索),有时也要像现实一样思考。

原文地址:https://www.cnblogs.com/Piers/p/7123775.html