Skip to content

Commit 0814bbc

Browse files
authored
Update Palindrome.java
Added a new recursive method (pointer based approach) to reduce multiple substring calls and added JUnit Tests for testing the edge cases.
1 parent be70801 commit 0814bbc

File tree

1 file changed

+66
-20
lines changed

1 file changed

+66
-20
lines changed
Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,104 @@
11
package com.thealgorithms.strings;
22

3-
/**
4-
* Wikipedia: https://en.wikipedia.org/wiki/Palindrome
5-
*/
6-
final class Palindrome {
3+
import org.junit.jupiter.api.Test;
4+
import static org.junit.jupiter.api.Assertions.*;
5+
6+
public final class Palindrome {
7+
78
private Palindrome() {
89
}
910

1011
/**
11-
* Check if a string is palindrome string or not using String Builder
12+
* Check if a string is palindrome or not using StringBuilder.
1213
*
1314
* @param s a string to check
14-
* @return {@code true} if given string is palindrome, otherwise
15-
* {@code false}
15+
* @return {@code true} if given string is palindrome, otherwise {@code false}
1616
*/
1717
public static boolean isPalindrome(String s) {
18-
return ((s == null || s.length() <= 1) || s.equals(new StringBuilder(s).reverse().toString()));
18+
if (s == null || s.length() <= 1) {
19+
return true;
20+
}
21+
String cleanedString = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
22+
return cleanedString.equals(new StringBuilder(cleanedString).reverse().toString());
1923
}
2024

2125
/**
22-
* Check if a string is palindrome string or not using recursion
26+
* Check if a string is palindrome using optimized recursion (pointer-based).
2327
*
2428
* @param s a string to check
25-
* @return {@code true} if given string is palindrome, otherwise
26-
* {@code false}
29+
* @return {@code true} if given string is palindrome, otherwise {@code false}
2730
*/
2831
public static boolean isPalindromeRecursion(String s) {
29-
if (s == null || s.length() <= 1) {
32+
if (s == null) {
3033
return true;
3134
}
35+
String cleanedString = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
36+
return isPalindromeRecursion(cleanedString, 0, cleanedString.length() - 1);
37+
}
3238

33-
if (s.charAt(0) != s.charAt(s.length() - 1)) {
39+
private static boolean isPalindromeRecursion(String s, int left, int right) {
40+
if (left >= right) {
41+
return true;
42+
}
43+
if (s.charAt(left) != s.charAt(right)) {
3444
return false;
3545
}
36-
37-
return isPalindromeRecursion(s.substring(1, s.length() - 1));
46+
return isPalindromeRecursion(s, left + 1, right - 1);
3847
}
3948

4049
/**
41-
* Check if a string is palindrome string or not using two pointer technique
50+
* Check if a string is palindrome using the two-pointer technique.
4251
*
4352
* @param s a string to check
44-
* @return {@code true} if given string is palindrome, otherwise
45-
* {@code false}
53+
* @return {@code true} if given string is palindrome, otherwise {@code false}
4654
*/
4755
public static boolean isPalindromeTwoPointer(String s) {
4856
if (s == null || s.length() <= 1) {
4957
return true;
5058
}
51-
for (int i = 0, j = s.length() - 1; i < j; ++i, --j) {
52-
if (s.charAt(i) != s.charAt(j)) {
59+
String cleanedString = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
60+
int left = 0;
61+
int right = cleanedString.length() - 1;
62+
while (left < right) {
63+
if (cleanedString.charAt(left) != cleanedString.charAt(right)) {
5364
return false;
5465
}
66+
left++;
67+
right--;
5568
}
5669
return true;
5770
}
71+
72+
/**
73+
* JUnit Test Cases for the Palindrome methods
74+
*/
75+
public static class PalindromeTest {
76+
77+
@Test
78+
void testIsPalindrome() {
79+
assertTrue(Palindrome.isPalindrome("madam"));
80+
assertFalse(Palindrome.isPalindrome("hello"));
81+
assertTrue(Palindrome.isPalindrome("A man, a plan, a canal: Panama"));
82+
assertTrue(Palindrome.isPalindrome(""));
83+
assertTrue(Palindrome.isPalindrome("a"));
84+
}
85+
86+
@Test
87+
void testIsPalindromeRecursion() {
88+
assertTrue(Palindrome.isPalindromeRecursion("racecar"));
89+
assertFalse(Palindrome.isPalindromeRecursion("world"));
90+
assertTrue(Palindrome.isPalindromeRecursion("A man, a plan, a canal, Panama"));
91+
assertTrue(Palindrome.isPalindromeRecursion("a"));
92+
assertTrue(Palindrome.isPalindromeRecursion(null));
93+
}
94+
95+
@Test
96+
void testIsPalindromeTwoPointer() {
97+
assertTrue(Palindrome.isPalindromeTwoPointer("madam"));
98+
assertFalse(Palindrome.isPalindromeTwoPointer("hello"));
99+
assertTrue(Palindrome.isPalindromeTwoPointer("A man, a plan, a canal: Panama"));
100+
assertTrue(Palindrome.isPalindromeTwoPointer("a"));
101+
assertTrue(Palindrome.isPalindromeTwoPointer(null));
102+
}
103+
}
58104
}

0 commit comments

Comments
 (0)