Maximum Number Of Non Overlapping Palindrome Substrings

Solution For Maximum Number Of Non Overlapping Palindrome Substrings

Problem Statement:

Given a string s, find the maximum number of non-overlapping palindromic substrings of s.

Example:

Input: “ababcbacadefegdehijhklij”
Output: 7
Explanation: The optimal way to split this string is “ababa”, “c”, “a”, “defegde”, “hijh”, “kl”, “ij”, hence a total of 7 substrings.

Solution:

We can solve this problem using dynamic programming. Let’s define dp[i] as the maximum number of non-overlapping palindromic substrings ending at index i in the given string. To calculate dp[i], we can try to extend all the previously calculated palindromes.

For each index i, we can consider two cases:

  1. We can extend a palindrome that ends at i – 1 to include i. If s[j:i] is a palindrome (where j = i – length + 1 and length is the length of the palindrome ending at i – 1), we can extend this palindrome to include i. In this case, dp[i] will be equal to dp[j-1] + 1.

  2. We can consider a palindrome ending at i that does not overlap with any palindrome ending before i. In this case, dp[i] will be equal to dp[i-1] + 1.

We need to take the maximum of these two cases and store it in dp[i].

At the end, dp[n-1] will give us the maximum number of non-overlapping palindromic substrings in the given string.

For the implementation, we need to find all the palindromes ending at index i. We can do this by expanding around the center of the palindrome.

Here is the Python code for the solution:

def countSubstrings(s: str) -> int:
n = len(s)
dp = [0] * n

for i in range(n):
    # Case 2: consider palindrome ending at i that does not overlap with any palindrome ending before i
    dp[i] = dp[i-1] + 1
    # Case 1: try to extend all previously calculated palindromes
    for j in range(i):
        length = i - j + 1
        if s[j:i+1] == s[j:i+1][::-1] and (length <= 2 or dp[j-1] != 0):
            dp[i] = max(dp[i], dp[j-1] + 1)

return dp[n-1]

Time Complexity: O(n^2) where n is the length of the given string.

Space Complexity: O(n) as we are storing the dp array of size n.

Step by Step Implementation For Maximum Number Of Non Overlapping Palindrome Substrings

public class Solution {
    public int countSubstrings(String s) {
        // corner case
        if (s == null || s.length() == 0) return 0;
        
        // dp[i][j]: whether substring s[i...j] is a palindrome
        boolean[][] dp = new boolean[s.length()][s.length()];
        
        // initialize
        int res = 0;
        for (int i = 0; i < s.length(); i++) {
            dp[i][i] = true;
            res++;
        }
        
        // transition
        for (int i = s.length() - 2; i >= 0; i--) {
            for (int j = i + 1; j < s.length(); j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    if (j == i + 1) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                } else {
                    dp[i][j] = false;
                }
                
                if (dp[i][j]) res++;
            }
        }
        
        return res;
    }
}
def maxNumOfNonOverlappingPalindromeSubstrings(s): 

# create a list to store the results 

result = [] 

# create a list of all possible palindromes 

palindromes = getAllPalindromes(s) 

# sort the list of palindromes in descending order of length 

palindromes.sort(key = lambda x: len(x), reverse = True) 

# for each palindrome in the list, check if it can be added to the result 

for palindrome in palindromes: 

if canAddToResult(palindrome, result): 

result.append(palindrome) 

return result 

def getAllPalindromes(s): 

# create an empty list to store the results 

result = [] 

# for each index i in the string s, find all palindromes that start at index i 

for i in range(len(s)): 

# find all odd length palindromes starting at index i 

result.extend(getAllOddLengthPalindromes(s, i)) 

# find all even length palindromes starting at index i 

result.extend(getAllEvenLengthPalindromes(s, i)) 

return result 

def getAllOddLengthPalindromes(s, i): 

# create an empty list to store the results 

result = [] 

# for each index j starting from i, find all odd length palindromes that start at index i and end at index j 

for j in range(i, len(s)): 

# if s[i] is equal to s[j], it is a potential palindrome 

if s[i] == s[j]: 

# if s[i+1] is equal to s[j-1], it is a palindrome 

if i+1 <= j-1 and s[i+1] == s[j-1]: 

result.append(s[i:j+1]) 

return result 

def getAllEvenLengthPalindromes(s, i): 

# create an empty list to store the results 

result = [] 

# for each index j starting from i+1, find all even length palindromes that start at index i and end at index j 

for j in range(i+1, len(s)): 

# if s[i] is equal to s[j], it is a potential palindrome 

if s[i] == s[j]: 

# if s[i+1] is equal to s[j-1], it is a palindrome 

if i+1 <= j-1 and s[i+1] == s[j-1]: 

result.append(s[i:j+1]) 

return result 

def canAddToResult(palindrome, result): 

# for each string in the result, check if the palindrome overlaps with it 

for string in result: 

if isOverlap(palindrome, string): 

return False 

return True 

def isOverlap(s1, s2): 

# check if the two strings overlap 

return s1 in s2 or s2 in s1
var maxNumOfPalindromeSubstrings = function(s) {
    // your code here
};
One possible solution is to use a brute force approach, where we check every substring to see if it is a palindrome. If it is, we add it to our list of palindromes. We can then return the length of this list.

int findMaxNumOfPalindromes(string s) {
    int n = s.length();
    vector palindromes;
    // check every substring
    for (int i = 0; i < n; i++) {
        for (int j = i+1; j <= n; j++) {
            string sub = s.substr(i, j-i);
            // check if substring is a palindrome
            if (isPalindrome(sub)) {
                palindromes.push_back(sub);
            }
        }
    }
    return palindromes.size();
}

// helper function to check if a string is a palindrome
bool isPalindrome(string s) {
    int n = s.length();
    for (int i = 0; i < n/2; i++) {
        if (s[i] != s[n-1-i]) {
            return false;
        }
    }
    return true;
}
public class Solution {
    public int CountSubstrings(string s) {
        int n = s.Length;
        int[,] dp = new int[n,n];
        int count = 0;
        for(int i=0; i


Scroll to Top

Top 100 Leetcode Practice Problems In Java

Get 30% Off Instantly!
[gravityforms id="5" description="false" titla="false" ajax="true"]