代码改变世界

LeetCode 5 最长对称串

2019-04-28 22:48  yx1989  阅读(100)  评论(0编辑  收藏  举报

LeetCode 5 最长对称串

最早时候做这道题的时候还是用Java写的,用的是字符串匹配的思路,一直Time Limit Exceeded。甚至还想过用KMP开优化子串查找。

public class Solution {
    public String longestPalindrome(String s) {
        String reverseS = new StringBuilder(s).reverse().toString();

        String maxMatch = "";
        for (int i = 0; i < reverseS.length(); i++) {
            String match = maxMatch(s, reverseS, i);
            if (match.length() > maxMatch.length()) {
                maxMatch = match;
            }
            
            if (maxMatch.length() > s.length() / 2 + 1) {
                break;
            }
        }
        return maxMatch;
    }

    /**
     * 在s中查找符合pattern匹配的最长子串
     *
     * TODO 使用KMP优化
     */
    public String maxMatch(String s, String pattern, int pBegin) {
        int sBegin = 0;
        int sIndex = sBegin;
        int pIndex = pBegin;

        String maxMatch = "";

        while (sIndex < s.length() && pIndex < pattern.length()) {
            if (s.charAt(sIndex) == pattern.charAt(pIndex)) {
                String substring = pattern.substring(pBegin, pIndex + 1);
                if (substring.length() > maxMatch.length()
                        && (substring.length() == 1 || (pattern.length() - pIndex - 1 == sIndex - substring.length()  + 1))) {
                    maxMatch = substring;
                }

                sIndex++;
                pIndex++;

            } else {
                sBegin += 1;
                sIndex = sBegin;
                pIndex = pBegin;
            }
        }

        return maxMatch;
    }
}

后来做字符串题多了之后,开始熟悉双指针的方法。所谓对称,其实就是从中间往两边查找,如果都一样就继续;不一样就是匹配失败。

"cbbd" 这种情况没有太好的方法,只好两种都尝试一下。

func longestPalindrome(s string) string {
	maxLength := 0
	begin := 0
	if len(s) < 2 {
		return s
	}
	for i := 0; i < len(s); i++ {
		var left, right int
		left = i - 1
		right = i + 1
		begin, maxLength = findMax(s, left, right, begin, maxLength)
		if i+2 <= len(s) && s[i] == s[i+1] {
			left = i - 1
			right = i + 2
			begin, maxLength = findMax(s, left, right, begin, maxLength)
		}

	}
	return s[begin : begin+maxLength]
}

func findMax(s string, left int, right int, begin int, maxLength int) (int, int) {
	for left >= 0 && right < len(s) && s[left] == s[right] {
		left--
		right++
	}
	if maxLength < right-left-1 {
		begin = left + 1
		maxLength = right - left - 1
	}
	return begin, maxLength
}