HomeLeetcode132. Palindrome Partitioning II - Leetcode Solutions

132. Palindrome Partitioning II – Leetcode Solutions

Description:

Given a string s, partition s such that every substring of the partition is a 

palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

Examples:

Example 1:

Input: s = "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.

Example 2:

Input: s = "a"
Output: 0
Example 3:

Input: s = "ab"
Output: 1

Solution in Python:

Problem Breakdown

We need to partition the given string s such that each substring in the partition is a palindrome, and we want to minimize the number of cuts required.

Approach

  1. Dynamic Programming: We’ll use a DP approach to solve this problem efficiently.
  2. Palindrome Check: We will precompute whether any substring s[i:j+1] is a palindrome or not using a 2D boolean array is_palindrome.
  3. Minimum Cuts Calculation: We will use a 1D array cuts where cuts[i] represents the minimum cuts needed for the substring s[0:i+1].

Steps

  1. Initialize the is_palindrome array:
    • is_palindrome[i][j] is True if the substring s[i:j+1] is a palindrome.
    • To fill this array, we use the property of palindromes: a substring s[i:j+1] is a palindrome if s[i] == s[j] and s[i+1:j] is also a palindrome.
  2. Initialize the cuts array:
    • cuts[i] starts as i, which is the maximum number of cuts needed (worst case: every character is a palindrome by itself).
  3. Update the cuts array:
    • If s[0:i+1] is a palindrome, then no cut is needed for this substring, so cuts[i] = 0.
    • Otherwise, find the minimum cuts needed by checking all possible previous cuts.
Python
class Solution:
    def minCut(self, s: str) -> int:
        n = len(s)
        # Initialize a 2D array to store palindrome status
        is_palindrome = [[False] * n for _ in range(n)]
        
        # Every single character is a palindrome
        for i in range(n):
            is_palindrome[i][i] = True
        
        # Fill the is_palindrome table
        for length in range(2, n + 1):  # length of the substring
            for start in range(n - length + 1):
                end = start + length - 1
                if length == 2:
                    is_palindrome[start][end] = (s[start] == s[end])
                else:
                    is_palindrome[start][end] = (s[start] == s[end] and is_palindrome[start + 1][end - 1])
        
        # Initialize the cuts array
        cuts = [0] * n
        for i in range(n):
            # If the whole substring s[0:i+1] is a palindrome, no cut is needed
            if is_palindrome[0][i]:
                cuts[i] = 0
            else:
                # Set initial cuts[i] to the maximum possible cuts (cut before every character)
                cuts[i] = i
                for j in range(1, i + 1):
                    if is_palindrome[j][i]:
                        cuts[i] = min(cuts[i], cuts[j - 1] + 1)
        
        return cuts[n - 1]

Explanation

  1. Palindrome Table Initialization:
    • We first assume that every single character is a palindrome.
    • We then check substrings of length 2 and above to update the palindrome status in the is_palindrome table.
  2. Cuts Calculation:
    • We check for each substring if it’s a palindrome from the beginning. If it is, no cut is needed.
    • Otherwise, for each substring, we find the minimum cuts needed by checking possible positions for previous cuts where the substring could be divided into palindromes.

This approach ensures that we efficiently compute the minimum cuts needed for palindrome partitioning using dynamic programming.

Solution in Javascript:

JavaScript
/**
 * @param {string} s
 * @return {number}
 */
var minCut = function(s) {
    const n = s.length;
    // Initialize a 2D array to store palindrome status
    const isPalindrome = Array.from({ length: n }, () => Array(n).fill(false));

    // Every single character is a palindrome
    for (let i = 0; i < n; i++) {
        isPalindrome[i][i] = true;
    }

    // Fill the isPalindrome table
    for (let length = 2; length <= n; length++) {  // length of the substring
        for (let start = 0; start <= n - length; start++) {
            const end = start + length - 1;
            if (length == 2) {
                isPalindrome[start][end] = (s[start] === s[end]);
            } else {
                isPalindrome[start][end] = (s[start] === s[end] && isPalindrome[start + 1][end - 1]);
            }
        }
    }

    // Initialize the cuts array
    const cuts = Array(n).fill(0);
    for (let i = 0; i < n; i++) {
        // If the whole substring s[0:i+1] is a palindrome, no cut is needed
        if (isPalindrome[0][i]) {
            cuts[i] = 0;
        } else {
            // Set initial cuts[i] to the maximum possible cuts (cut before every character)
            cuts[i] = i;
            for (let j = 1; j <= i; j++) {
                if (isPalindrome[j][i]) {
                    cuts[i] = Math.min(cuts[i], cuts[j - 1] + 1);
                }
            }
        }
    }

    return cuts[n - 1];
};

Solution in Java:

Java
class Solution {
    public int minCut(String s) {
        int n = s.length();
        // Initialize a 2D array to store palindrome status
        boolean[][] isPalindrome = new boolean[n][n];

        // Every single character is a palindrome
        for (int i = 0; i < n; i++) {
            isPalindrome[i][i] = true;
        }

        // Fill the isPalindrome table
        for (int length = 2; length <= n; length++) {  // length of the substring
            for (int start = 0; start <= n - length; start++) {
                int end = start + length - 1;
                if (length == 2) {
                    isPalindrome[start][end] = (s.charAt(start) == s.charAt(end));
                } else {
                    isPalindrome[start][end] = (s.charAt(start) == s.charAt(end) && isPalindrome[start + 1][end - 1]);
                }
            }
        }

        // Initialize the cuts array
        int[] cuts = new int[n];
        for (int i = 0; i < n; i++) {
            // If the whole substring s[0:i+1] is a palindrome, no cut is needed
            if (isPalindrome[0][i]) {
                cuts[i] = 0;
            } else {
                // Set initial cuts[i] to the maximum possible cuts (cut before every character)
                cuts[i] = i;
                for (int j = 1; j <= i; j++) {
                    if (isPalindrome[j][i]) {
                        cuts[i] = Math.min(cuts[i], cuts[j - 1] + 1);
                    }
                }
            }
        }

        return cuts[n - 1];
    }
}

Solution in C#:

C#
public class Solution {
    public int MinCut(string s) {
        int n = s.Length;
        // Initialize a 2D array to store palindrome status
        bool[,] isPalindrome = new bool[n, n];

        // Every single character is a palindrome
        for (int i = 0; i < n; i++) {
            isPalindrome[i, i] = true;
        }

        // Fill the isPalindrome table
        for (int length = 2; length <= n; length++) {  // length of the substring
            for (int start = 0; start <= n - length; start++) {
                int end = start + length - 1;
                if (length == 2) {
                    isPalindrome[start, end] = (s[start] == s[end]);
                } else {
                    isPalindrome[start, end] = (s[start] == s[end] && isPalindrome[start + 1, end - 1]);
                }
            }
        }

        // Initialize the cuts array
        int[] cuts = new int[n];
        for (int i = 0; i < n; i++) {
            // If the whole substring s[0:i+1] is a palindrome, no cut is needed
            if (isPalindrome[0, i]) {
                cuts[i] = 0;
            } else {
                // Set initial cuts[i] to the maximum possible cuts (cut before every character)
                cuts[i] = i;
                for (int j = 1; j <= i; j++) {
                    if (isPalindrome[j, i]) {
                        cuts[i] = Math.Min(cuts[i], cuts[j - 1] + 1);
                    }
                }
            }
        }

        return cuts[n - 1];
    }
}

Subscribe
Notify of

0 Comments
Inline Feedbacks
View all comments

Popular