[exploration intermediate algorithm] longest palindrome substring

Keywords: Mobile

This question can refer to: 647. Palindrome substring

In essence, it is the same. Judge all palindrome strings and find the longest one.

Central expansion method

Center extension is to take each letter of a given string as the center and extend it to both sides to find the longest subpalindrome string. Algorithm complexity is O(N^2)

public String longestPalindrome(String s) {
    if (s == null || s.length() < 1) return "";
    char[] strs = s.toCharArray();
    int len = strs.length;
    int[] arr1 = new int[2];
    int[] arr2 = new int[2];
    //Record the location of the start and end points
    int start = 0, end = 0;
    for (int i = 0; i < len; i++) {
        //Taking s(i) as the center and spreading to both sides, the longest palindrome substring is obtained
        get(arr1, strs, i - 1, i + 1);
        //Taking s(i) and s(i+1) as centers, the longest palindrome substring is obtained
        get(arr2, strs, i, i + 1);
        int tmpStart, tmpEnd;
        if (arr1[1] - arr1[0] > arr2[1] - arr2[0]) {
            tmpStart = arr1[0];
            tmpEnd = arr1[1];
        } else {
            tmpStart = arr2[0];
            tmpEnd = arr2[1];
        }
        if ((tmpEnd - tmpStart) > (end - start)) {
            start = tmpStart;
            end = tmpEnd;
        }
    }
    return s.substring(start, end + 1);
}
public void get(int[] arr, char[] strs, int left, int right) {
    while (left >= 0 && right < strs.length && strs[left] == strs[right]) {
        --left;
        ++right;
    }
    ++left;
    --right;
    arr[0] = left;
    arr[1] = right;
}

Based on dynamic planning

public String longestPalindrome(String s) {
    if (s == null || s.length() < 1) return "";
    int len = s.length();
    boolean dp[][] = new boolean[len][len];
    char[] strs = s.toCharArray();
    int start = 0, end = 0;
    // Judge whether dp[i][i+1] is palindrome
    for (int i = 0; i < len -1 ; i++) {
        if(strs[i] == strs[i + 1]) {
            dp[i][i + 1] = true;
            start = i;
            end = i + 1;
        }
		// dp[i][i] means that a single letter must be palindrome
        dp[i][i] = true;
    }	
    //Because the last letter cannot be set in the above loop, it should be set here
    dp[len - 1][len - 1] = true;

	// According to DP [i] [J] = (DP [i + 1] [J - 1] & & (STRs [i] = = STRs [J])) 
	// To determine whether dp[i][j] is palindrome
	// If so, is it longer than the original longest and recorded
    for (int i = len - 3; i >= 0; i--) {
        for (int j = i+2; j < len; j++) {
            dp[i][j] = (dp[i + 1][j - 1] && (strs[i] == strs[j]));
            if (dp[i][j]) {
                if (j - i > end - start) {
                    start = i;
                    end = j;
                }
            }
        }
    }
    return s.substring(start, end + 1);
}

dp[i][j] indicates whether the substring s[i,j] of S is palindrome.

It should be noted that the order of traversal of the second cycle is shown in the following figure (the broken line represents the order of calculation):

Posted by -Mike- on Thu, 12 Dec 2019 11:31:34 -0800