×

Palindrome Partitioning problem in Java

In this article, you will be acknowledged about partitioning of the palindrome. It can be done in many ways. This article makes sure every method is discussed.

Palindrome

If a string remains unchanged whether it is read from the left to the right or the right to the left, it is considered to be a palindrome.

Palindrome Partitioning

When a string is partitioned into palindromes, it is done so that each substring created from the original string is really a palindrome in and of itself. In the Java palindrome partitioning issue, we provide the lowest number of cuts needed to convert each of the provided string's substrings into a palindrome. Let's break it down with the aid of some examples.

A matrix chain multiplication issue variant is this one. The string is simply returned as 0, if it is a palindrome. If not, we attempt to make cuts in every location that is feasible, recursively determine the cost for each cut, and then return the minimal value, similar to a Matrix Chain Multiplication issue.

Take str as the input string, and let minPalPartion() return the function that requires the fewest cuts to partition a palindrome.

Example:

Str = “madam”

At most cuts needed to the above string are 0. Since the string is a palindrome.

Str = “kebab”

At most cuts needed to the above string are 2. Since the string is not a palindrome. We may divide the provided text into 3 substrings using the 2 cuts, each of which is a palindrome.

There are many approaches in which a palindrome partitioning can be achieved. They are

  • By recursion
  • By Dynamic programming
  • By memorization

By Recursion

Let us understand the partitioning of palindrome by recursion method

File name: Recurpalin.java

// Java program for implementation of palindrome partitioning by recursion method
public class Recurpalin
{
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;
}
public static void main(String args[])
{
String str = "kebab";
System.out.println("At most cuts needed in "
+ "Palindrome Partitioning is " + minPalPartion(str, 0, str.length() - 1));
}
}

Output

At most cuts needed in Palindrome Partitioning is 2

By Dynamic Programming

The dynamic programming solution is shown below. It seems to use the calculated values and stores the responses to the subproblems in two arrays. Let u sunderstand it through the program flow.

Let us understand the program flow for achieving the palindrome partitioning. The approach that discussed below implements the dynamic programming. It is not really a program but the function body of how the methodology is implemented for partitioning the palindrome. It was proved that this approach isn’t the perfect approach. We are using for loops that are nested to a threshold of three to locate the solution. This consumes a lot of time for execution of program. So an optimized approach is also discovered.

class Dynampalin {


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];
}
}

Now let us go through the program that runs with a optimized approach. The interviewer will typically reject the above solution, but they can also ask that you enhance it. The offered solution never possesses the third level of for-loop nesting. The logic after optimization has been found that the time consumption or the time complexity is comparatively less than the previously discussed function. Hence this method is more often used for the purpose of palindrome partitioning. 

File name: Dynampalin1.java

//Java program for implementation of palindrome partitioning by dynamic programming    //method
public class Dynampalin1{
static int minPalPartion(String str)
{
int n = str.length();
int[] C = new int[n];
boolean[][] P = new boolean[n][n];


int i, j, k, L; 
for (i = 0; i < n; i++) {
P[i][i] = true;
}
/* Substring length L is. Consider all substrings with lengths ranging from 2 to n as you build the solution from the bottom up.*/
for (L = 2; L <= n; L++) {
// Different starting indexes should be established for a substring of\
                                       //length L.
for (i = 0; i < n - L + 1; i++) {
j = i + L - 1; // Set ending index
// We just need to compare two characters if L is 2. 
                                                      //Otherwise,two corner characters must be checked.
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];
}
}
}
// Obtain the string's minimum cut value.
return C[n - 1];
}
public static void main(String args[])
{
String str = "kebab";
System.out.println("At most cuts needed in "
+ "Palindrome Partitioning"
+ " is " + minPalPartion(str));
}
}

Output

At most cuts needed in Palindrome Partitioning is 2

By Memorization

The fundamental concept is to cache the sporadic results computed by recursive functions. These outcomes can be placed in a hashmap or unordered map.

The starting and ending indexes of the text will be used to construct the keys for such hashmap, so ["start index".append("end index")] would be the key.

Let us understand the below program for understanding the above approach.

File name: Memopalin.java

import java.io.*;
import java.util.*;


class Memopalin {
// Leveraging memorization to overcome the partition problems.


// method to determine whether an input string is a palindrome
static boolean ispalindrome(String input, int start, int end)
{
// Using the two-pointer method to verify palindrome
while (start < end) {
if (input.charAt(start) != input.charAt(end))
return false;
start++;
end--;
}
return true;
}


// method to retrieve keys for hashmap
static String convert(int a, int b)
{
return String.valueOf(a) + "" + String.valueOf(b);
}


/* Returns the smallest number of cuts necessary to divide a string into sections where each one is a palindrome.*/
static int minpalparti_memo(String input, int i, int j, HashMap<String, Integer> memo)
{
if (i > j)
return 0;
// The input string's key
String ij = convert(i, j);


/* If the number of partitions for the string "ij" has already been determined, then use the Hashmap to return the calculated result.*/
if (memo.containsKey(ij)) {
return memo.get(ij);
}
// A palindrome exists for every String of size 1.
if (i == j) {
memo.put(ij, 0);
return 0;
}
if (ispalindrome(input, i, j)) {
memo.put(ij, 0);
return 0;
}
int minimum = Integer.MAX_VALUE;
// Make cuts from I to j in every direction that is possible.
for (int k = i; k < j; k++) {
int left_min = Integer.MAX_VALUE;
int right_min = Integer.MAX_VALUE;
String left = convert(i, k);
String right = convert(k + 1, j);


// if the left cut is already clear
if (memo.containsKey(left)) {
left_min = memo.get(left);
}
// if the appropriate cut is already discovered
if (memo.containsKey(right)) {
right_min = memo.get(right);
}


// the left as well as right strings are calculated recursively
if (left_min == Integer.MAX_VALUE)
left_min = minpalparti_memo(input, i, k, memo);
if (right_min == Integer.MAX_VALUE)
right_min = minpalparti_memo(input, k + 1, j, memo);


// minimising all potential cuts to k
minimum = Math.min(minimum, left_min + 1 + right_min);
}
memo.put(ij, minimum);
// For the entire string, return the minimum cut value.
return memo.get(ij);
}

public static void main(String args[])
{
String input = "kebab";
HashMap<String, Integer> memo = new HashMap<>();
System.out.println(minpalparti_memo(input, 0, input.length() - 1, memo));
}
}

Output

At most cuts required in palindrome partitioning are 2

Related Topics

Sort Elements by Frequency in Java

To sort the elements in Java by using frequency, we need an input array. We should create a function that sorts the elements in an array by using their frequencies...

3 minutes read.

Byte to Hex in Java

Java exclusively uses byte data types to store in a byte array, which is an array. Each component of a byte array has a default value of 0. Hex String -...

3 minutes read.

Add Time in Java

Before Java 8, java.util.Date was one of the most usually involved classes for addressing date-time values in java. Then Java 8 presented java.time.LocalDateTime and java.time.ZonedDateTime. Java 8 likewise permits us...

6 minutes read.

java.lang.NumberFormatException for Input String

java.lang.NumberFormatException for Input String The exception java.lang.NumberFormatException for input string occurs when we try to convert a string into a number format. For example, if someone converts the string “Tutorial & Example”...

3 minutes read.

Static class in Java

In Java, a class is a file containing the Java byte code. It can essentially specifically be executed on the JVM (Java Virtual Machine), fairly significant. The JVM is mostly...

7 minutes read.

Classes and Objects in Java Example Programs

Classes and Objects in Java Example Programs Java is an Object-Oriented programming language, i.e., everything in Java is associated with objects and objects are associated with classes. The classes and objects...

5 minutes read.

Producer consumer problem in Java using Synchronised block

The producer-consumer problem in Java, commonly known as the bounded-buffer problem, is a well-known multi-process synchronization challenge where we attempt to synchronize many processes. Two processes are involved in the producer-consumer problem:...

3 minutes read.

Tree Implementation in Java

Introduction to Tree A non-linear, hierarchical data structure called a "tree" is made up of a number of nodes, each of which contains a values and a sequence of pointers to...

14 minutes read.

Java Math subtractExact() Method

The subtractExact() method of Java Math class returns mathematical difference of the specified two arguments, throwing an exception if the result overflows int or long. Syntax: public static int subtractExact (int x,...

1 minute read.

Permutation Coefficient in Java

In this tutorial, we will get familiar with the permutation coefficient in Java.  We will understand it through examples and see different approaches to solving the problem. A permutation is a...

5 minutes read.

Array Programs in Java

Array Programs in Java: An array is a data structure that stores similar elements in a contiguous memory location. In Java, an array is an object that stores the same...

7 minutes read.

Best Practices to use String Class in Java

Use String Builder or String Buffer for String concatenation in place of + operator.Compare two strings by equals( ) method instead == operator.Call .equals( ) method on a known String...

3 minutes read.

Java try catch

Java try catch There can be statements that can cause exceptions, and the exception leads to abnormal termination of the program. To avoid that abnormal termination, those statements that look potent...

4 minutes read.

Reverse a String using Collections in Java

Generally, a String is a grouping of characters. Yet, in Java, a String is an item that addresses a succession of characters. The Java.lang.String class is utilized to make a...

5 minutes read.

ArrayList vs Vector in Java

ArrayList Vs. Vector in Java In Java, the two classes ArrayList and Vector both are associated with Java Collections Framework. Both classes implement java.util.List interface. Even so, these classes have noticeable...

4 minutes read.

Java Pi

What is Pi? There are many formulas in geometry that employ the Pi constant to calculate things like circumference, area, and volume. A circle's circumference divided by its diameter yields a...

3 minutes read.

String Handling Method in Java

What is a String? Strings are a bundle of different characters that are normally used in Java programming language. Strings are regarded as objects in the Java programming language. “String” is a...

4 minutes read.

How to add 6 Months to the Current Date in Java?

In this tutorial, we will learn how to add 6 months to the local or current date in Java language. We will begin our topic with basic concepts and would...

3 minutes read.

Types of Assignment Operators in Java

In this tutorial, we are going to study assignment operators and their types in Java language. Before proceeding to the types, let us know the term ‘assignment operator’.  The assignment...

5 minutes read.

Interface Program in Java

Interface Program in Java In the previous topic, we discussed that abstraction is possible through the interface and abstract class. An abstract class provides partial to 100% abstraction. 100 %abstraction in...

4 minutes read.