Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 66 additions & 20 deletions src/main/java/com/thealgorithms/strings/Palindrome.java
Original file line number Diff line number Diff line change
@@ -1,58 +1,104 @@
package com.thealgorithms.strings;

/**
* Wikipedia: https://en.wikipedia.org/wiki/Palindrome
*/
final class Palindrome {
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public final class Palindrome {

private Palindrome() {
}

/**
* Check if a string is palindrome string or not using String Builder
* Check if a string is palindrome or not using StringBuilder.
*
* @param s a string to check
* @return {@code true} if given string is palindrome, otherwise
* {@code false}
* @return {@code true} if given string is palindrome, otherwise {@code false}
*/
public static boolean isPalindrome(String s) {
return ((s == null || s.length() <= 1) || s.equals(new StringBuilder(s).reverse().toString()));
if (s == null || s.length() <= 1) {
return true;
}
String cleanedString = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
return cleanedString.equals(new StringBuilder(cleanedString).reverse().toString());
}

/**
* Check if a string is palindrome string or not using recursion
* Check if a string is palindrome using optimized recursion (pointer-based).
*
* @param s a string to check
* @return {@code true} if given string is palindrome, otherwise
* {@code false}
* @return {@code true} if given string is palindrome, otherwise {@code false}
*/
public static boolean isPalindromeRecursion(String s) {
if (s == null || s.length() <= 1) {
if (s == null) {
return true;
}
String cleanedString = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
return isPalindromeRecursion(cleanedString, 0, cleanedString.length() - 1);
}

if (s.charAt(0) != s.charAt(s.length() - 1)) {
private static boolean isPalindromeRecursion(String s, int left, int right) {
if (left >= right) {
return true;
}
if (s.charAt(left) != s.charAt(right)) {
return false;
}

return isPalindromeRecursion(s.substring(1, s.length() - 1));
return isPalindromeRecursion(s, left + 1, right - 1);
}

/**
* Check if a string is palindrome string or not using two pointer technique
* Check if a string is palindrome using the two-pointer technique.
*
* @param s a string to check
* @return {@code true} if given string is palindrome, otherwise
* {@code false}
* @return {@code true} if given string is palindrome, otherwise {@code false}
*/
public static boolean isPalindromeTwoPointer(String s) {
if (s == null || s.length() <= 1) {
return true;
}
for (int i = 0, j = s.length() - 1; i < j; ++i, --j) {
if (s.charAt(i) != s.charAt(j)) {
String cleanedString = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
int left = 0;
int right = cleanedString.length() - 1;
while (left < right) {
if (cleanedString.charAt(left) != cleanedString.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}

/**
* JUnit Test Cases for the Palindrome methods
*/
public static class PalindromeTest {

@Test
void testIsPalindrome() {
assertTrue(Palindrome.isPalindrome("madam"));
assertFalse(Palindrome.isPalindrome("hello"));
assertTrue(Palindrome.isPalindrome("A man, a plan, a canal: Panama"));
assertTrue(Palindrome.isPalindrome(""));
assertTrue(Palindrome.isPalindrome("a"));
}

@Test
void testIsPalindromeRecursion() {
assertTrue(Palindrome.isPalindromeRecursion("racecar"));
assertFalse(Palindrome.isPalindromeRecursion("world"));
assertTrue(Palindrome.isPalindromeRecursion("A man, a plan, a canal, Panama"));
assertTrue(Palindrome.isPalindromeRecursion("a"));
assertTrue(Palindrome.isPalindromeRecursion(null));
}

@Test
void testIsPalindromeTwoPointer() {
assertTrue(Palindrome.isPalindromeTwoPointer("madam"));
assertFalse(Palindrome.isPalindromeTwoPointer("hello"));
assertTrue(Palindrome.isPalindromeTwoPointer("A man, a plan, a canal: Panama"));
assertTrue(Palindrome.isPalindromeTwoPointer("a"));
assertTrue(Palindrome.isPalindromeTwoPointer(null));
}
}
}
Loading