• Palindrome Algorithm Questions


    Given a string which we can delete at most k, return whether you can make a palindrome.

    For example, given 'waterrfetawx' and a k of 2, you could delete f and x to get 'waterretaw'.

    Notice the recursive structure of this problem:

    • If the string is already a palindrome, then we can just return true.
    • If the string is not already a palindrome, then try getting rid of the first or last character that does not contribute to its palindromicity.

    This takes O(2min(n, k)) time, where n is the length of the original string. This is because we call k_palindrome twice on each subproblem, and on each call, either k or the string gets reduced by at least 1.

    class Solution {   
        public boolean canMakePalindrome(String s, int k) {
            return canMakePalindromeHelper(s, 0, s.length() - 1, k);
        }
    
        private boolean canMakePalindromeHelper(String s, int start, int end, int k) {
            while(start < end) {
                if(s.charAt(start) == s.charAt(end)) {
                    start++;
                    end--;
                }
                else {
                    break;
                }
            }
            if(start == end) {
                return true;
            }
            if(k == 0) {
                return false;
            }
            return canMakePalindromeHelper(s, start + 1, end, k - 1) || canMakePalindromeHelper(s, start, end - 1, k - 1);
        }
    }

    Dynamic Programming, O(n^2 * k) runtime, O(n^2 * k) space

    dp[i][j][k]:  if the substring s[i - j] can make a palindrome with at most k deletions. 

    dp[i][j][k] = dp[i + 1][j - 1][k] if s[i] == s[j];  dp[i][j][k] = dp[i + 1][j][k - 1] || dp[i][j - 1][k - 1] if s[i] != s[j];

    substring of length 1 and 2 needs to be initialized first.

    class Solution {    
        public boolean canMakePalindrome(String s, int k) {
            int n = s.length();
            boolean[][][] dp = new boolean[n][n][k + 1];
            for(int i = 0; i < n; i++) {
                for(int del = 0; del <= k; del++) {
                    dp[i][i][del] = true;
                }
            }
            for(int startIdx = 0; startIdx <= n - 2; startIdx++) {
                int endIdx = startIdx + 1;
                for(int del = 0; del <= k; del++) {
                    if(del == 0 && s.charAt(startIdx) == s.charAt(endIdx) || del > 0) {
                        dp[startIdx][endIdx][del] = true;
                    }
                }
            }
            for(int del = 0; del <= k; del++) {
                for(int l = 3; l <= n; l++) {
                    for(int startIdx = 0; startIdx <= n - l; startIdx++) {
                        int endIdx = startIdx + l - 1;
                        if(startIdx == 1 && endIdx == 9 && del == 1) {
                            System.out.println();
                        }
                        if(s.charAt(startIdx) == s.charAt(endIdx)) {
                            dp[startIdx][endIdx][del] = dp[startIdx + 1][endIdx - 1][del];
                        }
                        else if(del > 0) {
                            dp[startIdx][endIdx][del] = (dp[startIdx + 1][endIdx][del - 1] || dp[startIdx][endIdx - 1][del - 1]);
                        }
                    }
                }
            }
            for(int del = 0; del <= k; del++) {
                if(dp[0][n - 1][del]) {
                    return true;
                }
            }
            return false;
        }
    }

    Dynamic Programming, convert to the Longest Palindromic Subsequence problem.  O(n^2) runtime, O(n^2) space 

    Find the length of the longest palindromic subsequence using the same optimal substructure, let it be longest. If s.length() - longest <= k, then return true, otherwise return false.

    class Solution {
        public boolean canMakePalindrome(String s, int k) {
            int longest = longestPalindromeSubseq(s);
            return s.length() - longest <= k;
        }
    
        private int longestPalindromeSubseq(String s) {
            if(s == null || s.length() == 0){
                return 0;
            }
            int n = s.length();
            int[][] dp = new int[n][n];
            for(int i = 0; i < n; i++){
                dp[i][i] = 1;
            }
            for(int i = 0; i < n - 1; i++){
                dp[i][i + 1] = s.charAt(i) == s.charAt(i + 1) ? 2 : 1;
            }
            for(int l = 3; l <= n; l++){
                for(int startIdx = 0; startIdx <= n - l; startIdx++){
                    int endIdx = startIdx + l - 1;
                    if(s.charAt(startIdx) == s.charAt(endIdx)){
                        dp[startIdx][endIdx] = dp[startIdx + 1][endIdx - 1] + 2;
                    }
                    else{
                        dp[startIdx][endIdx] = Math.max(dp[startIdx + 1][endIdx], dp[startIdx][endIdx - 1]);
                    }
                }
            }
            return dp[0][n - 1];
        }
    }

    LeetCode 1147. Longest Chunked Palindrome Decomposition

    Return the largest possible k such that there exists a_1, a_2, ..., a_k such that:

    • Each a_i is a non-empty string;
    • Their concatenation a_1 + a_2 + ... + a_k is equal to text;
    • For all 1 <= i <= k,  a_i = a_{k+1 - i}.

    Example 1:

    Input: text = "ghiabcdefhelloadamhelloabcdefghi"
    Output: 7
    Explanation: We can split the string on "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)".
    

    Example 2:

    Input: text = "merchant"
    Output: 1
    Explanation: We can split the string on "(merchant)".
    

    Example 3:

    Input: text = "antaprezatepzapreanta"
    Output: 11
    Explanation: We can split the string on "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)".
    

    Example 4:

    Input: text = "aaa"
    Output: 3
    Explanation: We can split the string on "(a)(a)(a)".
    

    Constraints:

    • text consists only of lowercase English characters.
    • 1 <= text.length <= 1000

    1. O(N^3) Dp solution

    dp[i][j]: the longest chunked palindrome decomposition for text[i, j].

    dp[i][j] = Max of {1, max of {dp[i1 + 1][j1 - 1] + 2, for all text[i, i1] == text[j1, j] and i1 < j1}}

    Init: for all dp[i][j] where i <= j, dp[i][j] = 1, we can always get at least 1 if we don't do any split. If i > j, dp[i][j] = 0, meaning there is no middle substring left after removing palindrome chunk from both sides.

    Answer: dp[0][N - 1].

    class Solution {
        public int longestDecomposition(String text) {
            int n = text.length();
            int[][] dp = new int[n][n];
            int leftEnd = n % 2 != 0 ? n / 2 : n / 2 - 1;
            int rightStart = n / 2;
            for(int i = leftEnd, j = rightStart; i >= 0 && j < n; i--, j++) {
                dp[i][j] = 1;
                for(int i1 = i, j1 = j; i1 < j1; i1++, j1--) {
                    if(text.substring(i, i1 + 1).equals(text.substring(j1, j + 1))) {
                        dp[i][j] = Math.max(dp[i1 + 1][j1 - 1] + 2, dp[i][j]);
                    }
                }
            }
            return dp[0][n - 1];
        }
    }
  • 相关阅读:
    jQuery遍历div,判断是否为空,为空时执行某个操作
    ps中扩展画布的时候,不能选择扩展画布部分的颜色解决方法
    PS中缩放工具的细微缩放不可以使用的解决方法
    Excel的基础操作
    Word文档编辑
    人脸识别活体检测之张张嘴和眨眨眼——login.jsp
    人脸识别活体检测之张张嘴和眨眨眼——web.xml
    人脸识别活体检测之张张嘴和眨眨眼——readme
    maven用途、核心概念、用法、常用参数和命令、扩展
    [转载]ORACLE临时表的创建
  • 原文地址:https://www.cnblogs.com/lz87/p/10619175.html
Copyright © 2020-2023  润新知