# Palindrome Partitioning | DP-17

• Difficulty Level : Hard
• Last Updated : 24 Nov, 2021

Given a string, a partitioning of the string is a palindrome partitioning if every substring of the partition is a palindrome. For example, “aba|b|bbabb|a|b|aba” is a palindrome partitioning of “ababbbabbababa”. Determine the fewest cuts needed for a palindrome partitioning of a given string. For example, minimum of 3 cuts are needed for “ababbbabbababa”. The three cuts are “a|babbbab|b|ababa”. If a string is a palindrome, then minimum 0 cuts are needed. If a string of length n containing all different characters, then minimum n-1 cuts are needed. Become a success story instead of just reading about them. Prepare for coding interviews at Amazon and other top product-based companies with our Amazon Test Series. Includes topic-wise practice questions on all important DSA topics along with 10 practice contests of 2 hours each. Designed by industry experts that will surely help you practice and sharpen your programming skills. Wait no more, start your preparation today!

Examples :

Input : str = “geek”
Output : 2
We need to make minimum 2 cuts, i.e., “g ee k”
Input : str = “aaaa”
Output : 0
The string is already a palindrome.
Input : str = “abcde”
Output : 4
Input : str = “abbac”
Output : 1

This problem is a variation of Matrix Chain Multiplication problem. If the string is a palindrome, then we simply return 0. Else, like the Matrix Chain Multiplication problem, we try making cuts at all possible places, recursively calculate the cost for each cut and return the minimum value.
Let the given string be str and minPalPartion() be the function that returns the fewest cuts needed for palindrome partitioning. following is the optimal substructure property.

Using Recursion

```// i is the starting index and j is the ending index. i must be passed as 0 and j as n-1
minPalPartion(str, i, j) = 0 if i == j. // When string is of length 1.
minPalPartion(str, i, j) = 0 if str[i..j] is palindrome.

// If none of the above conditions is true, then minPalPartion(str, i, j) can be
// calculated recursively using the following formula.
minPalPartion(str, i, j) = Min { minPalPartion(str, i, k) + 1 +
minPalPartion(str, k+1, j) }
where k varies from i to j-1```

## C++

 `// C++ Code for Palindrome Partitioning``// Problem``#include ``using` `namespace` `std;` `bool` `isPalindrome(string String, ``int` `i, ``int` `j)``{``    ``while``(i < j)``    ``{``      ``if``(String[i] != String[j])``        ``return` `false``; ``      ``i++;``      ``j--;``    ``}``    ``return` `true``;``}``int` `minPalPartion(string String, ``int` `i, ``int` `j)``{``    ``if``( i >= j || isPalindrome(String, i, j) )``      ``return` `0;``    ``int` `ans = INT_MAX, count;``    ``for``(``int` `k = i; k < j; k++)``    ``{``      ``count = minPalPartion(String, i, k) +``        ``minPalPartion(String, k + 1, j) + 1;`` ` `      ``ans = min(ans, count);``    ``}``    ``return` `ans;``}``// Driver code``int` `main() {``    ``string str = ``"ababbbabbababa"``;``    ``cout << ``"Min cuts needed for "` `<<``      ``"Palindrome Partitioning is "` `<< ``      ``minPalPartion(str, 0, str.length() - 1) << endl;``    ``return` `0;``}``// This code is contributed by rag2127`

## Java

 `// Java Code for Palindrome Partitioning``// Problem``public` `class` `GFG``{` `  ``static` `boolean` `isPalindrome(String string, ``int` `i, ``int` `j)``  ``{``    ``while``(i < j)``    ``{``      ``if``(string.charAt(i) != string.charAt(j))``        ``return` `false``; ``      ``i++;``      ``j--;``    ``}``    ``return` `true``;``  ``}` `  ``static` `int` `minPalPartion(String string, ``int` `i, ``int` `j)``  ``{   ``    ``if``( i >= j || isPalindrome(string, i, j) )``      ``return` `0``;``    ``int` `ans = Integer.MAX_VALUE, count;``    ``for``(``int` `k = i; k < j; k++)``    ``{``      ``count = minPalPartion(string, i, k) +``        ``minPalPartion(string, k + ``1``, j) + ``1``;` `      ``ans = Math.min(ans, count);``    ``}``    ``return` `ans;``  ``}` `  ``// Driver code``  ``public` `static` `void` `main(String args[])``  ``{``    ``String str = ``"ababbbabbababa"``;``    ``System.out.println(``"Min cuts needed for "``                       ``+ ``"Palindrome Partitioning is "` `+ minPalPartion(str, ``0``, str.length() - ``1``));``  ``}``}` `// This code is contributed by adityapande88.`

## Python3

 `# Python code for implementation of Naive Recursive``# approach``def` `isPalindrome(x):``    ``return` `x ``=``=` `x[::``-``1``]`  `def` `minPalPartion(string, i, j):``    ``if` `i >``=` `j ``or` `isPalindrome(string[i:j ``+` `1``]):``        ``return` `0``    ``ans ``=` `float``(``'inf'``)``    ``for` `k ``in` `range``(i, j):``        ``count ``=` `(``            ``1` `+` `minPalPartion(string, i, k)``            ``+` `minPalPartion(string, k ``+` `1``, j)``        ``)``        ``ans ``=` `min``(ans, count)``    ``return` `ans`  `def` `main():``    ``string ``=` `"ababbbabbababa"``     ``print``(``     ``"Min cuts needed for Palindrome Partitioning is "``,``     ``minPalPartion(string, ``0``, ``len``(string) ``-` `1``),``    ``)` `if` `__name__ ``=``=` `"__main__"``:``    ``main()` `# This code is contributed by itsvinayak`

## C#

 `// C# Code for Palindrome Partitioning``// Problem``using` `System;``public` `class` `GFG``{` `  ``static` `bool` `isPalindrome(``string` `String, ``int` `i, ``int` `j)``  ``{``    ``while``(i < j)``    ``{``      ``if``(String[i] != String[j])``        ``return` `false``; ``      ``i++;``      ``j--;``    ``}``    ``return` `true``;``  ``}` `  ``static` `int` `minPalPartion(``string` `String, ``int` `i, ``int` `j)``  ``{   ``    ``if``( i >= j || isPalindrome(String, i, j) )``      ``return` `0;``    ``int` `ans = Int32.MaxValue, count;``    ``for``(``int` `k = i; k < j; k++)``    ``{``      ``count = minPalPartion(String, i, k) +``        ``minPalPartion(String, k + 1, j) + 1;` `      ``ans = Math.Min(ans, count);``    ``}``    ``return` `ans;``  ``}` `  ``// Driver code``  ``static` `public` `void` `Main (){``    ``string` `str = ``"ababbbabbababa"``;``    ``Console.WriteLine(``"Min cuts needed for "``+``                      ``"Palindrome Partitioning is "` `+``                      ``minPalPartion(str, 0, str.Length - 1));``  ``}``}` `// This code is contributed by avanitrachhadiya2155`

## Javascript

 ``

Output:

`Min cuts needed for Palindrome Partitioning is 3 `

Using Dynamic Programming :
Following is Dynamic Programming solution. It stores the solutions to subproblems in two arrays P[][] and C[][], and reuses the calculated values.

## C++

 `// Dynamic Programming Solution for``// Palindrome Partitioning Problem``#include ``using` `namespace` `std;` `// Returns the minimum number of cuts``// needed to partition a string``// such that every part is a palindrome``int` `minPalPartion(string str)``{``    ``// Get the length of the string``    ``int` `n = str.length();` `    ``/* Create two arrays to build the solution``       ``in bottom up manner``    ``C[i][j] = Minimum number of cuts needed for``              ``palindrome partitioning``              ``of substring str[i..j]``    ``P[i][j] = true if substring str[i..j] is``              ``palindrome, else false``    ``Note that C[i][j] is 0 if P[i][j] is true */``    ``int` `C[n][n];``    ``bool` `P[n][n];` `    ``// Every substring of length 1 is a palindrome``    ``for` `(``int` `i = 0; i < n; i++) {``        ``P[i][i] = ``true``;``        ``C[i][i] = 0;``    ``}` `    ``/* L is substring length. Build the``    ``solution in bottom up manner by``    ``considering all substrings of``    ``length starting from 2 to n.``    ``The loop structure is same as Matrix``    ``Chain Multiplication problem``    ``( See https:// www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/ )*/``    ``for` `(``int` `L = 2; L <= n; L++) {` `        ``// For substring of length L, set``        ``// different possible starting indexes``        ``for` `(``int` `i = 0; i < n - L + 1; i++) {``            ``int` `j = i + L - 1; ``// Set ending index` `            ``// If L is 2, then we just need to``            ``// compare two characters. Else``            ``// need to check two corner characters``            ``// and value of P[i+1][j-1]``            ``if` `(L == 2)``                ``P[i][j] = (str[i] == str[j]);``            ``else``                ``P[i][j] = (str[i] == str[j]) && P[i + 1][j - 1];` `            ``// IF str[i..j] is palindrome, then C[i][j] is 0``            ``if` `(P[i][j] == ``true``)``                ``C[i][j] = 0;``            ``else` `{` `                ``// Make a cut at every possible``                ``// location starting from i to j,``                ``// and get the minimum cost cut.``                ``C[i][j] = INT_MAX;``                ``for` `(``int` `k = i; k <= j - 1; k++)``                    ``C[i][j] = min(C[i][j], C[i][k] + C[k + 1][j] + 1);``            ``}``        ``}``    ``}` `    ``// Return the min cut value for``    ``// complete string. i.e., str[0..n-1]``    ``return` `C[n - 1];``}` `// Driver code``int` `main()``{``    ``string str = ``"ababbbabbababa"``;``    ``cout << ``"Min cuts needed for Palindrome"``            ``" Partitioning is "``         ``<< minPalPartion(str);``    ``return` `0;``}` `// This code is contributed by rathbhupendra`

## C

 `// Dynamic Programming Solution for Palindrome Partitioning Problem``#include ``#include ``#include ` `// A utility function to get minimum of two integers``int` `min(``int` `a, ``int` `b) { ``return` `(a < b) ? a : b; }` `// Returns the minimum number of cuts needed to partition a string``// such that every part is a palindrome``int` `minPalPartion(``char``* str)``{``    ``// Get the length of the string``    ``int` `n = ``strlen``(str);` `    ``/* Create two arrays to build the solution in bottom up manner``       ``C[i][j] = Minimum number of cuts needed for palindrome partitioning``                 ``of substring str[i..j]``       ``P[i][j] = true if substring str[i..j] is palindrome, else false``       ``Note that C[i][j] is 0 if P[i][j] is true */``    ``int` `C[n][n];``    ``bool` `P[n][n];` `    ``int` `i, j, k, L; ``// different looping variables` `    ``// Every substring of length 1 is a palindrome``    ``for` `(i = 0; i < n; i++) {``        ``P[i][i] = ``true``;``        ``C[i][i] = 0;``    ``}` `    ``/* L is substring length. Build the solution in bottom up manner by``       ``considering all substrings of length starting from 2 to n.``       ``The loop structure is same as Matrix Chain Multiplication problem (``       ``See https:// www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/ )*/``    ``for` `(L = 2; L <= n; L++) {``        ``// For substring of length L, set different possible starting indexes``        ``for` `(i = 0; i < n - L + 1; i++) {``            ``j = i + L - 1; ``// Set ending index` `            ``// If L is 2, then we just need to compare two characters. Else``            ``// need to check two corner characters and value of P[i+1][j-1]``            ``if` `(L == 2)``                ``P[i][j] = (str[i] == str[j]);``            ``else``                ``P[i][j] = (str[i] == str[j]) && P[i + 1][j - 1];` `            ``// IF str[i..j] is palindrome, then C[i][j] is 0``            ``if` `(P[i][j] == ``true``)``                ``C[i][j] = 0;``            ``else` `{` `                ``// Make a cut at every possible location starting from i to j,``                ``// and get the minimum cost cut.``                ``C[i][j] = INT_MAX;``                ``for` `(k = i; k <= j - 1; k++)``                    ``C[i][j] = min(C[i][j], C[i][k] + C[k + 1][j] + 1);``            ``}``        ``}``    ``}` `    ``// Return the min cut value for complete string. i.e., str[0..n-1]``    ``return` `C[n - 1];``}` `// Driver program to test above function``int` `main()``{``    ``char` `str[] = ``"ababbbabbababa"``;``    ``printf``(``"Min cuts needed for Palindrome Partitioning is %d"``,``           ``minPalPartion(str));``    ``return` `0;``}`

## Java

 `// Java Code for Palindrome Partitioning``// Problem``public` `class` `GFG {``    ``// Returns the minimum number of cuts needed``    ``// to partition a string such that every``    ``// part is a palindrome``    ``static` `int` `minPalPartion(String str)``    ``{``        ``// Get the length of the string``        ``int` `n = str.length();` `        ``/* Create two arrays to build the solution``           ``in bottom up manner``           ``C[i][j] = Minimum number of cuts needed``                     ``for palindrome partitioning``                     ``of substring str[i..j]``           ``P[i][j] = true if substring str[i..j] is``                     ``palindrome, else false``           ``Note that C[i][j] is 0 if P[i][j] is``           ``true */``        ``int``[][] C = ``new` `int``[n][n];``        ``boolean``[][] P = ``new` `boolean``[n][n];` `        ``int` `i, j, k, L; ``// different looping variables` `        ``// Every substring of length 1 is a palindrome``        ``for` `(i = ``0``; i < n; i++) {``            ``P[i][i] = ``true``;``            ``C[i][i] = ``0``;``        ``}` `        ``/* L is substring length. Build the solution in``         ``bottom up manner by considering all substrings``         ``of length starting from 2 to n. The loop``         ``structure is same as Matrix Chain Multiplication``         ``problem (``        ``See https:// www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/ )*/``        ``for` `(L = ``2``; L <= n; L++) {``            ``// For substring of length L, set different``            ``// possible starting indexes``            ``for` `(i = ``0``; i < n - L + ``1``; i++) {``                ``j = i + L - ``1``; ``// Set ending index` `                ``// If L is 2, then we just need to``                ``// compare two characters. Else need to``                ``// check two corner characters and value``                ``// of P[i+1][j-1]``                ``if` `(L == ``2``)``                    ``P[i][j] = (str.charAt(i) == str.charAt(j));``                ``else``                    ``P[i][j] = (str.charAt(i) == str.charAt(j)) && P[i + ``1``][j - ``1``];` `                ``// IF str[i..j] is palindrome, then``                ``// C[i][j] is 0``                ``if` `(P[i][j] == ``true``)``                    ``C[i][j] = ``0``;``                ``else` `{``                    ``// Make a cut at every possible``                    ``// localtion starting from i to j,``                    ``// and get the minimum cost cut.``                    ``C[i][j] = Integer.MAX_VALUE;``                    ``for` `(k = i; k <= j - ``1``; k++)``                        ``C[i][j] = Integer.min(C[i][j],``                                              ``C[i][k] + C[k + ``1``][j] + ``1``);``                ``}``            ``}``        ``}` `        ``// Return the min cut value for complete``        ``// string. i.e., str[0..n-1]``        ``return` `C[``0``][n - ``1``];``    ``}` `    ``// Driver program to test above function``    ``public` `static` `void` `main(String args[])``    ``{``        ``String str = ``"ababbbabbababa"``;``        ``System.out.println(``"Min cuts needed for "``                           ``+ ``"Palindrome Partitioning is "` `+ minPalPartion(str));``    ``}``}``// This code is contributed by Sumit Ghosh`

## Python3

 `# Dynamic Programming Solution for``# Palindrome Partitioning Problem` `# Returns the minimum number of``# cuts needed to partition a string``# such that every part is a palindrome``def` `minPalPartion(``str``):``    ` `    ``# Get the length of the string``    ``n ``=` `len``(``str``)``    ` `    ``# Create two arrays to build the``    ``# solution in bottom up manner``    ``# C[i][j] = Minimum number of cuts``    ``# needed for palindrome``    ``# partitioning of substring str[i..j]``    ``# P[i][j] = true if substring str[i..j]``    ``# is palindrome, else false. Note that``    ``# C[i][j] is 0 if P[i][j] is true``    ``C ``=` `[[``0` `for` `i ``in` `range``(n)]``            ``for` `i ``in` `range``(n)]``    ``P ``=` `[[``False` `for` `i ``in` `range``(n)]``                ``for` `i ``in` `range``(n)]` `    ``# different looping variables``    ``j ``=` `0``    ``k ``=` `0``    ``L ``=` `0``    ` `    ``# Every substring of length``    ``# 1 is a palindrome``    ``for` `i ``in` `range``(n):``        ``P[i][i] ``=` `True``;``        ``C[i][i] ``=` `0``;``        ` `    ``# L is substring length. Build the``    ``# solution in bottom-up manner by``    ``# considering all substrings of``    ``# length starting from 2 to n.``    ``# The loop structure is the same as``    ``# Matrix Chain Multiplication problem ``    ``# (See https://www.geeksforgeeks.org / matrix-chain-multiplication-dp-8/ )``    ``for` `L ``in` `range``(``2``, n ``+` `1``):``        ` `        ``# For substring of length L, set``        ``# different possible starting indexes``        ``for` `i ``in` `range``(n ``-` `L ``+` `1``):``            ``j ``=` `i ``+` `L ``-` `1` `# Set ending index``            ` `            ``# If L is 2, then we just need to``            ``# compare two characters. Else``            ``# need to check two corner characters``            ``# and value of P[i + 1][j-1]``            ``if` `L ``=``=` `2``:``                ``P[i][j] ``=` `(``str``[i] ``=``=` `str``[j])``            ``else``:``                ``P[i][j] ``=` `((``str``[i] ``=``=` `str``[j]) ``and``                             ``P[i ``+` `1``][j ``-` `1``])``                             ` `            ``# IF str[i..j] is palindrome,``            ``# then C[i][j] is 0``            ``if` `P[i][j] ``=``=` `True``:``                ``C[i][j] ``=` `0``            ``else``:``                ` `                ``# Make a cut at every possible``                ``# location starting from i to j,``                ``# and get the minimum cost cut.``                ``C[i][j] ``=` `100000000``                ``for` `k ``in` `range``(i, j):``                    ``C[i][j] ``=` `min` `(C[i][j], C[i][k] ``+``                                   ``C[k ``+` `1``][j] ``+` `1``)``                                   ` `    ``# Return the min cut value for``    ``# complete string. i.e., str[0..n-1]``    ``return` `C[``0``][n ``-` `1``]` `# Driver code``str` `=` `"ababbbabbababa"``print` `(``'Min cuts needed for Palindrome Partitioning is'``,``                                     ``minPalPartion(``str``))``                                      ` `# This code is contributed``# by Sahil shelangia`

## C#

 `// C# Code for Palindrome Partitioning``// Problem``using` `System;` `class` `GFG {``    ``// Returns the minimum number of cuts needed``    ``// to partition a string such that every``    ``// part is a palindrome``    ``static` `int` `minPalPartion(String str)``    ``{``        ``// Get the length of the string``        ``int` `n = str.Length;` `        ``/* Create two arrays to build the solution``        ``in bottom up manner``        ``C[i][j] = Minimum number of cuts needed``                    ``for palindrome partitioning``                    ``of substring str[i..j]``        ``P[i][j] = true if substring str[i..j] is``                    ``palindrome, else false``        ``Note that C[i][j] is 0 if P[i][j] is``        ``true */``        ``int``[, ] C = ``new` `int``[n, n];``        ``bool``[, ] P = ``new` `bool``[n, n];` `        ``int` `i, j, k, L; ``// different looping variables` `        ``// Every substring of length 1 is a palindrome``        ``for` `(i = 0; i < n; i++) {``            ``P[i, i] = ``true``;``            ``C[i, i] = 0;``        ``}` `        ``/* L is substring length. Build the solution in``        ``bottom up manner by considering all substrings``        ``of length starting from 2 to n. The loop``        ``structure is same as Matrix Chain Multiplication``        ``problem (``        ``See https:// www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/ )*/``        ``for` `(L = 2; L <= n; L++) {``            ``// For substring of length L, set different``            ``// possible starting indexes``            ``for` `(i = 0; i < n - L + 1; i++) {``                ``j = i + L - 1; ``// Set ending index` `                ``// If L is 2, then we just need to``                ``// compare two characters. Else need to``                ``// check two corner characters and value``                ``// of P[i+1][j-1]``                ``if` `(L == 2)``                    ``P[i, j] = (str[i] == str[j]);``                ``else``                    ``P[i, j] = (str[i] == str[j]) && P[i + 1, j - 1];` `                ``// IF str[i..j] is palindrome, then``                ``// C[i][j] is 0``                ``if` `(P[i, j] == ``true``)``                    ``C[i, j] = 0;``                ``else` `{``                    ``// Make a cut at every possible``                    ``// localtion starting from i to j,``                    ``// and get the minimum cost cut.``                    ``C[i, j] = ``int``.MaxValue;``                    ``for` `(k = i; k <= j - 1; k++)``                        ``C[i, j] = Math.Min(C[i, j], C[i, k]``                                                        ``+ C[k + 1, j] + 1);``                ``}``            ``}``        ``}` `        ``// Return the min cut value for complete``        ``// string. i.e., str[0..n-1]``        ``return` `C[0, n - 1];``    ``}` `    ``// Driver program``    ``public` `static` `void` `Main()``    ``{``        ``String str = ``"ababbbabbababa"``;``        ``Console.Write(``"Min cuts needed for "``                      ``+ ``"Palindrome Partitioning is "` `+ minPalPartion(str));``    ``}``}` `// This code is contributed by Sam007`

## PHP

 ``

Output:

`Min cuts needed for Palindrome Partitioning is 3 `

Time Complexity: O(n3)

We can optimize the above code a bit further. Instead of calculating C[i] separately in O(n^2), we can do it with the P[i] itself. Below is the highly optimized code of this problem:

## C++

 `#include ``using` `namespace` `std;` `int` `minCut(string a)``{``    ``int` `cut[a.length()];``    ``bool` `palindrome[a.length()][a.length()];``    ``memset``(palindrome, ``false``, ``sizeof``(palindrome));``    ``for` `(``int` `i = 0; i < a.length(); i++)``    ``{``        ``int` `minCut = i;``        ``for` `(``int` `j = 0; j <= i; j++)``        ``{``            ``if` `(a[i] == a[j] && (i - j < 2 || palindrome[j + 1][i - 1]))``            ``{``                ``palindrome[j][i] = ``true``;``                ``minCut = min(minCut, j == 0 ? 0 : (cut[j - 1] + 1));``            ``}``        ``}``        ``cut[i] = minCut;``    ``}``    ``return` `cut[a.length() - 1];``}` `// Driver code``int` `main()``{``    ``cout << minCut(``"aab"``) << endl;``    ``cout << minCut(``"aabababaxx"``) << endl;``    ``return` `0;``}` `// This code is contributed by divyesh072019.`

## Java

 `import` `java.io.*;` `class` `GFG {` `    ``public` `static` `int` `minCut(String a)``    ``{``        ``int``[] cut = ``new` `int``[a.length()];``        ``boolean``[][] palindrome = ``new` `boolean``[a.length()][a.length()];` `        ``for` `(``int` `i = ``0``; i < a.length(); i++) {``            ``int` `minCut = i;``            ``for` `(``int` `j = ``0``; j <= i; j++) {``                ``if` `(a.charAt(i) == a.charAt(j) && (i - j < ``2` `|| palindrome[j + ``1``][i - ``1``])) {``                    ``palindrome[j][i] = ``true``;``                    ``minCut = Math.min(minCut, j == ``0` `? ``0` `: (cut[j - ``1``] + ``1``));``                ``}``            ``}``            ``cut[i] = minCut;``        ``}` `        ``return` `cut[a.length() - ``1``];``    ``}` `    ``public` `static` `void` `main(String[] args)``    ``{``        ``System.out.println(minCut(``"aab"``));``        ``System.out.println(minCut(``"aabababaxx"``));``    ``}``}`

## Python3

 `def` `minCut(a):` `    ``cut ``=` `[``0` `for` `i ``in` `range``(``len``(a))]``    ``palindrome ``=` `[[``False` `for` `i ``in` `range``(``len``(a))] ``for` `j ``in` `range``(``len``(a))]``    ``for` `i ``in` `range``(``len``(a)):``        ``minCut ``=` `i;``        ``for` `j ``in` `range``(i ``+` `1``):``            ``if` `(a[i] ``=``=` `a[j] ``and` `(i ``-` `j < ``2` `or` `palindrome[j ``+` `1``][i ``-` `1``])):      ``                ``palindrome[j][i] ``=` `True``;``                ``minCut ``=` `min``(minCut,``0` `if`  `j ``=``=` `0` `else` `(cut[j ``-` `1``] ``+` `1``));``        ``cut[i] ``=` `minCut;  ``    ``return` `cut[``len``(a) ``-` `1``];` `# Driver code``if` `__name__``=``=``'__main__'``:` `    ``print``(minCut(``"aab"``))``    ``print``(minCut(``"aabababaxx"``))``    ` `    ``# This code is contributed by rutvik_56`

## C#

 `using` `System;``using` `System.Collections.Generic;  ``class` `GFG``{  ``    ``static` `int` `minCut(``string` `a)``    ``{``        ``int``[] cut = ``new` `int``[a.Length];``        ``bool``[,] palindrome = ``new` `bool``[a.Length, a.Length];  ``        ``for` `(``int` `i = 0; i < a.Length; i++)``        ``{``            ``int` `minCut = i;``            ``for` `(``int` `j = 0; j <= i; j++)``            ``{``                ``if` `(a[i] == a[j] && (i - j < 2 ||``                                     ``palindrome[j + 1, i - 1]))``                ``{``                    ``palindrome[j, i] = ``true``;``                    ``minCut = Math.Min(minCut, j == 0 ? 0 : (cut[j - 1] + 1));``                ``}``            ``}``            ``cut[i] = minCut;``        ``}``        ``return` `cut[a.Length - 1];``    ``}``  ` `  ``// Driver code       ``  ``static` `void` `Main()``  ``{``    ``Console.WriteLine(minCut(``"aab"``));``    ``Console.WriteLine(minCut(``"aabababaxx"``));``  ``}``}` `// This code is contributed by divyeshrabadiya07.`

## Javascript

 ``

An optimization to above approach
In the above approach, we can calculate the minimum cut while finding all palindromic substring. If we find all palindromic substring 1st and then we calculate minimum cut, time complexity will reduce to O(n2).
Thanks for Vivek for suggesting this optimization.

## C++

 `// Dynamic Programming Solution for Palindrome Partitioning Problem``#include ``#include ``#include ``using` `namespace` `std;` `// A utility function to get minimum of two integers``int` `min(``int` `a, ``int` `b) { ``return` `(a < b) ? a : b; }` `// Returns the minimum number of cuts needed to partition a string``// such that every part is a palindrome``int` `minPalPartion(``char``* str)``{``  ` `    ``// Get the length of the string``    ``int` `n = ``strlen``(str);` `    ``/* Create two arrays to build the solution in bottom-up manner``       ``C[i] = Minimum number of cuts needed for a palindrome partitioning``                 ``of substring str[0..i]``       ``P[i][j] = true if substring str[i..j] is palindrome, else false``       ``Note that C[i] is 0 if P[i] is true */``    ``int` `C[n];``    ``bool` `P[n][n];` `    ``int` `i, j, k, L; ``// different looping variables` `    ``// Every substring of length 1 is a palindrome``    ``for` `(i = 0; i < n; i++) {``        ``P[i][i] = ``true``;``    ``}` `    ``/* L is substring length. Build the solution in bottom up manner by``       ``considering all substrings of length starting from 2 to n. */``    ``for` `(L = 2; L <= n; L++) {``        ``// For substring of length L, set different possible starting indexes``        ``for` `(i = 0; i < n - L + 1; i++) {``            ``j = i + L - 1; ``// Set ending index` `            ``// If L is 2, then we just need to compare two characters. Else``            ``// need to check two corner characters and value of P[i+1][j-1]``            ``if` `(L == 2)``                ``P[i][j] = (str[i] == str[j]);``            ``else``                ``P[i][j] = (str[i] == str[j]) && P[i + 1][j - 1];``        ``}``    ``}` `    ``for` `(i = 0; i < n; i++) {``        ``if` `(P[i] == ``true``)``            ``C[i] = 0;``        ``else` `{``            ``C[i] = INT_MAX;``            ``for` `(j = 0; j < i; j++) {``                ``if` `(P[j + 1][i] == ``true` `&& 1 + C[j] < C[i])``                    ``C[i] = 1 + C[j];``            ``}``        ``}``    ``}` `    ``// Return the min cut value for complete string. i.e., str[0..n-1]``    ``return` `C[n - 1];``}` `// Driver program to test above function``int` `main()``{``    ``char` `str[] = ``"ababbbabbababa"``;``    ``cout <<``"Min cuts needed for Palindrome Partitioning is "` `<< minPalPartion(str);``    ``return` `0;``}` `// This code is contributed by shivanisinghss2110`

## C

 `// Dynamic Programming Solution for Palindrome Partitioning Problem``#include ``#include ``#include ``#include ` `// A utility function to get minimum of two integers``int` `min(``int` `a, ``int` `b) { ``return` `(a < b) ? a : b; }` `// Returns the minimum number of cuts needed to partition a string``// such that every part is a palindrome``int` `minPalPartion(``char``* str)``{``    ``// Get the length of the string``    ``int` `n = ``strlen``(str);` `    ``/* Create two arrays to build the solution in bottom-up manner``       ``C[i] = Minimum number of cuts needed for a palindrome partitioning``                 ``of substring str[0..i]``       ``P[i][j] = true if substring str[i..j] is palindrome, else false``       ``Note that C[i] is 0 if P[i] is true */``    ``int` `C[n];``    ``bool` `P[n][n];` `    ``int` `i, j, k, L; ``// different looping variables` `    ``// Every substring of length 1 is a palindrome``    ``for` `(i = 0; i < n; i++) {``        ``P[i][i] = ``true``;``    ``}` `    ``/* L is substring length. Build the solution in bottom up manner by``       ``considering all substrings of length starting from 2 to n. */``    ``for` `(L = 2; L <= n; L++) {``        ``// For substring of length L, set different possible starting indexes``        ``for` `(i = 0; i < n - L + 1; i++) {``            ``j = i + L - 1; ``// Set ending index` `            ``// If L is 2, then we just need to compare two characters. Else``            ``// need to check two corner characters and value of P[i+1][j-1]``            ``if` `(L == 2)``                ``P[i][j] = (str[i] == str[j]);``            ``else``                ``P[i][j] = (str[i] == str[j]) && P[i + 1][j - 1];``        ``}``    ``}` `    ``for` `(i = 0; i < n; i++) {``        ``if` `(P[i] == ``true``)``            ``C[i] = 0;``        ``else` `{``            ``C[i] = INT_MAX;``            ``for` `(j = 0; j < i; j++) {``                ``if` `(P[j + 1][i] == ``true` `&& 1 + C[j] < C[i])``                    ``C[i] = 1 + C[j];``            ``}``        ``}``    ``}` `    ``// Return the min cut value for complete string. i.e., str[0..n-1]``    ``return` `C[n - 1];``}` `// Driver program to test above function``int` `main()``{``    ``char` `str[] = ``"ababbbabbababa"``;``    ``printf``(``"Min cuts needed for Palindrome Partitioning is %d"``,``           ``minPalPartion(str));``    ``return` `0;``}`

## Java

 `// Java Code for Palindrome Partitioning``// Problem``public` `class` `GFG {``    ``// Returns the minimum number of cuts needed``    ``// to partition a string such that every part``    ``// is a palindrome``    ``static` `int` `minPalPartion(String str)``    ``{``        ``// Get the length of the string``        ``int` `n = str.length();` `        ``/* Create two arrays to build the solution``        ``in bottom up manner``           ``C[i] = Minimum number of cuts needed for``           ``palindrome partitioning of substring``           ``str[0..i]``           ``P[i][j] = true if substring str[i..j] is``           ``palindrome, else false``           ``Note that C[i] is 0 if P[i] is true */``        ``int``[] C = ``new` `int``[n];``        ``boolean``[][] P = ``new` `boolean``[n][n];` `        ``int` `i, j, k, L; ``// different looping variables` `        ``// Every substring of length 1 is a palindrome``        ``for` `(i = ``0``; i < n; i++) {``            ``P[i][i] = ``true``;``        ``}` `        ``/* L is substring length. Build the solution``        ``in bottom up manner by considering all substrings``        ``of length starting from 2 to n. */``        ``for` `(L = ``2``; L <= n; L++) {``            ``// For substring of length L, set different``            ``// possible starting indexes``            ``for` `(i = ``0``; i < n - L + ``1``; i++) {``                ``j = i + L - ``1``; ``// Set ending index` `                ``// If L is 2, then we just need to``                ``// compare two characters. Else need to``                ``// check two corner characters and value``                ``// of P[i+1][j-1]``                ``if` `(L == ``2``)``                    ``P[i][j] = (str.charAt(i) == str.charAt(j));``                ``else``                    ``P[i][j] = (str.charAt(i) == str.charAt(j)) && P[i + ``1``][j - ``1``];``            ``}``        ``}` `        ``for` `(i = ``0``; i < n; i++) {``            ``if` `(P[``0``][i] == ``true``)``                ``C[i] = ``0``;``            ``else` `{``                ``C[i] = Integer.MAX_VALUE;``                ``for` `(j = ``0``; j < i; j++) {``                    ``if` `(P[j + ``1``][i] == ``true` `&& ``1` `+ C[j] < C[i])``                        ``C[i] = ``1` `+ C[j];``                ``}``            ``}``        ``}` `        ``// Return the min cut value for complete``        ``// string. i.e., str[0..n-1]``        ``return` `C[n - ``1``];``    ``}` `    ``// Driver program to test above function``    ``public` `static` `void` `main(String args[])``    ``{``        ``String str = ``"ababbbabbababa"``;``        ``System.out.println(``"Min cuts needed for "``                           ``+ ``"Palindrome Partitioning"``                           ``+ ``" is "` `+ minPalPartion(str));``    ``}``}``// This code is contributed by Sumit Ghosh`

## Python3

 `# Dynamic Programming Solution for``# Palindrome Partitioning Problem``import` `sys` `# Returns the minimum number of cuts``# needed to partition a string such``# that every part is a palindrome``def` `minPalPartion(str1):``    ` `    ``# Get the length of the string``    ``n ``=` `len``(str1);``    ` `    ``# Create two arrays to build the solution``    ``# in bottom up manner``    ``# C[i] = Minimum number of cuts needed``    ``# for palindrome partitioning of``    ``# substring str[0..i]``    ``# P[i][j] = true if substring str[i..j]``    ``# is palindrome, else false``    ``# Note that C[i] is 0 if P[i] is true``    ``C ``=` `[``0``]``*``(n ``+` `1``);``    ``P ``=` `[[``False` `for` `x ``in` `range``(n ``+` `1``)] ``for` `y ``in` `range``(n ``+` `1``)];``    ` `    ``# Every substring of length 1 is``    ``# a palindrome``    ``for` `i ``in` `range``(n):``        ``P[i][i] ``=` `True``;``    ` `    ``# L is substring length. Build the solution``    ``# in bottom up manner by considering all``    ``# substrings of length starting from 2 to n.``    ``for` `L ``in` `range``(``2``, n ``+` `1``):``        ` `        ``# For substring of length L, set``        ``# different possible starting indexes``        ``for` `i ``in` `range``(n ``-` `L ``+` `1``):``            ``j ``=` `i ``+` `L ``-` `1``;``            ` `            ``# Set ending index``            ``# If L is 2, then we just need to``            ``# compare two characters. Else need``            ``# to check two corner characters and``            ``# value of P[i + 1][j-1]``            ``if` `(L ``=``=` `2``):``                ``P[i][j] ``=` `(str1[i] ``=``=` `str1[j]);``            ``else``:``                ``P[i][j] ``=` `((str1[i] ``=``=` `str1[j]) ``and` `P[i ``+` `1``][j ``-` `1``]);``    ``for` `i ``in` `range``(n):``        ``if` `(P[``0``][i] ``=``=` `True``):``            ``C[i] ``=` `0``;``        ``else``:``            ``C[i] ``=` `sys.maxsize;``            ``for` `j ``in` `range``(i):``                ``if``(P[j ``+` `1``][i] ``=``=` `True` `and` `1` `+` `C[j] < C[i]):``                    ``C[i] ``=` `1` `+` `C[j];``    ` `    ``# Return the min cut value for complete``    ``# string. i.e., str[0..n-1]``    ``return` `C[n ``-` `1``];` `# Driver Code``str1 ``=` `"ababbbabbababa"``;``print``(``"Min cuts needed for Palindrome Partitioning is"``, minPalPartion(str1));` `# This code is contributed by mits`

## C#

 `// C# Code for Palindrome Partitioning``// Problem``using` `System;` `class` `GFG {` `    ``// Returns the minimum number of cuts needed``    ``// to partition a string such that every part``    ``// is a palindrome``    ``static` `int` `minPalPartion(String str)``    ``{``        ``// Get the length of the string``        ``int` `n = str.Length;` `        ``/* Create two arrays to build the solution``        ``in bottom up manner``        ``C[i] = Minimum number of cuts needed for``        ``palindrome partitioning of substring``        ``str[0..i]``        ``P[i][j] = true if substring str[i..j] is``        ``palindrome, else false``        ``Note that C[i] is 0 if P[i] is true */``        ``int``[] C = ``new` `int``[n];``        ``bool``[, ] P = ``new` `bool``[n, n];` `        ``int` `i, j, L; ``// different looping variables` `        ``// Every substring of length 1 is a palindrome``        ``for` `(i = 0; i < n; i++) {``            ``P[i, i] = ``true``;``        ``}` `        ``/* L is substring length. Build the solution``        ``in bottom up manner by considering all substrings``        ``of length starting from 2 to n. */``        ``for` `(L = 2; L <= n; L++) {``            ``// For substring of length L, set different``            ``// possible starting indexes``            ``for` `(i = 0; i < n - L + 1; i++) {``                ``j = i + L - 1; ``// Set ending index` `                ``// If L is 2, then we just need to``                ``// compare two characters. Else need to``                ``// check two corner characters and value``                ``// of P[i+1][j-1]``                ``if` `(L == 2)``                    ``P[i, j] = (str[i] == str[j]);``                ``else``                    ``P[i, j] = (str[i] == str[j]) && P[i + 1, j - 1];``            ``}``        ``}` `        ``for` `(i = 0; i < n; i++) {``            ``if` `(P[0, i] == ``true``)``                ``C[i] = 0;``            ``else` `{``                ``C[i] = ``int``.MaxValue;``                ``for` `(j = 0; j < i; j++) {``                    ``if` `(P[j + 1, i] == ``true` `&& 1 + C[j] < C[i])``                        ``C[i] = 1 + C[j];``                ``}``            ``}``        ``}` `        ``// Return the min cut value for complete``        ``// string. i.e., str[0..n-1]``        ``return` `C[n - 1];``    ``}` `    ``// Driver program``    ``public` `static` `void` `Main()``    ``{``        ``String str = ``"ababbbabbababa"``;``        ``Console.Write(``"Min cuts needed for "``                      ``+ ``"Palindrome Partitioning"``                      ``+ ``" is "` `+ minPalPartion(str));``    ``}``}` `// This code is contributed by Sam007`

## PHP

 ``

Output:

`Min cuts needed for Palindrome Partitioning is 3 `

Time Complexity: O(n2)

Using Memorization to solve this problem.
The basic idea is to cache the intermittent results calculated in recursive functions. We can put these results into a hashmap/unordered_map.
To calculate the keys for the Hashmap we will use the starting and end index of the string as the key i.e. [“start_index”.append(“end_index”)] would be the key for the Hashmap.

Below is the implementation of above approach :

## C++

 `// Using memoizatoin to solve the partition problem.``#include ``using` `namespace` `std;``// Function to check if input string is palindrome or not``bool` `is palindrome(string input, ``int` `start, ``int` `end)``{``    ``// Using two pointer technique to check palindrome``    ``while` `(start < end) {``        ``if` `(input[start] != input[end])``            ``return` `false``;``        ``start++;``        ``end--;``    ``}``    ``return` `true``;``}` `// Function to find keys for the Hashmap``string convert(``int` `a, ``int` `b)``{``    ``return` `to_string(a) + ``""` `+ to_string(b);``}` `// Returns the minimum number of cuts needed to partition a string``// such that every part is a palindrome``int` `minpalparti_memo(string input, ``int` `i, ``int` `j, unordered_map& memo)``{``    ``if` `(i > j)``        ``return` `0;``    ``// Key for the Input String``    ``string ij = convert(i, j);` `    ``// If the no of partitions for string "ij" is already calculated``    ``// then return the calculated value using the Hashmap``    ``if` `(memo.find(ij) != memo.end()) {``        ``return` `memo[ij];``    ``}``    ``// Every String of length 1 is a palindrome``    ``if` `(i == j) {``        ``memo[ij] = 0;``        ``return` `0;``    ``}``    ``if` `(ispalindrome(input, i, j)) {``        ``memo[ij] = 0;``        ``return` `0;``    ``}``    ``int` `minimum = INT_MAX;``    ``// Make a cut at every possible location starting from i to j``    ``for` `(``int` `k = i; k < j; k++) {``        ``int` `left_min = INT_MAX;``        ``int` `right_min = INT_MAX;``        ``string left = convert(i, k);``        ``string right = convert(k + 1, j);` `        ``// If left cut is found already``        ``if` `(memo.find(left) != memo.end()) {``            ``left_min = memo[left];``        ``}``        ``// If right cut is found already``        ``if` `(memo.find(right) != memo.end()) {``            ``right_min = memo[right];``        ``}` `        ``// Recursively calculating for left and right strings``        ``if` `(left_min == INT_MAX)``            ``left_min = minpalparti_memo(input, i, k, memo);``        ``if` `(right_min == INT_MAX)``            ``right_min = minpalparti_memo(input, k + 1, j, memo);` `        ``// Taking minimum of all k possible cuts``        ``minimum = min(minimum, left_min + 1 + right_min);``    ``}` `    ``memo[ij] = minimum;``    ``// Return the min cut value for complete string.``    ``return` `memo[ij];``}``int` `main()``{``    ``string input = ``"ababbbabbababa"``;``    ``unordered_map memo;``    ``cout << minpalparti_memo(input, 0, input.length() - 1, memo) << endl;``    ``return` `0;``}`

## Python3

 `# Using memoizatoin to solve the partition problem.` `# Function to check if input string is pallindrome or not``def` `ispallindrome(``input``, start, end):` `    ``# Using two pointer technique to check pallindrome``    ``while` `(start < end):``        ``if` `(``input``[start] !``=` `input``[end]):``            ``return` `False``;``        ``start ``+``=` `1``        ``end ``-``=` `1``    ``return` `True``;` `# Function to find keys for the Hashmap``def` `convert(a, b):``    ``return` `str``(a) ``+` `str``(b);` `# Returns the minimum number of cuts needed to partition a string``# such that every part is a palindrome``def` `minpalparti_memo(``input``, i, j, memo):` `    ``if` `(i > j):``        ``return` `0``;``      ` `    ``# Key for the Input String``    ``ij ``=` `convert(i, j);` `    ``# If the no of partitions for string "ij" is already calculated``    ``# then return the calculated value using the Hashmap``    ``if` `(ij ``in` `memo):``        ``return` `memo[ij];``    ` `    ``# Every String of length 1 is a pallindrome``    ``if` `(i ``=``=` `j):``        ``memo[ij] ``=` `0``;``        ``return` `0``;``    ``if` `(ispallindrome(``input``, i, j)):``        ``memo[ij] ``=` `0``;``        ``return` `0``;  ``    ``minimum ``=` `1000000000``    ` `    ``# Make a cut at every possible location starting from i to j``    ``for` `k ``in` `range``(i, j):``        ``left_min ``=` `1000000000``        ``right_min ``=` `1000000000``        ``left ``=` `convert(i, k);``        ``right ``=` `convert(k ``+` `1``, j);` `        ``# If left cut is found already``        ``if` `(left ``in` `memo):``            ``left_min ``=` `memo[left];``        ` `        ``# If right cut is found already``        ``if` `(right ``in` `memo):``            ``right_min ``=` `memo[right];``        ` `        ``# Recursively calculating for left and right strings``        ``if` `(left_min ``=``=` `1000000000``):``            ``left_min ``=` `minpalparti_memo(``input``, i, k, memo);``        ``if` `(right_min ``=``=` `1000000000``):``            ``right_min ``=` `minpalparti_memo(``input``, k ``+` `1``, j, memo);` `        ``# Taking minimum of all k possible cuts``        ``minimum ``=` `min``(minimum, left_min ``+` `1` `+` `right_min);``    ``memo[ij] ``=` `minimum;``    ` `    ``# Return the min cut value for complete string.``    ``return` `memo[ij];` `  ``# Driver code``if` `__name__``=``=``'__main__'``:` `    ``input` `=` `"ababbbabbababa"``;``    ``memo ``=` `dict``()``    ``print``(minpalparti_memo(``input``, ``0``, ``len``(``input``) ``-` `1``, memo))``    ` `# This code is contributed by Pratham76.`

Time Complexity: O(n2)

My Personal Notes arrow_drop_up