StringBuilder equals() method is not working as expected

86 Views Asked by At

I am solving the 125. Valid Palindrome problem in leetcode. For testcase

A man, a plan, a canal: Panama

with below code, it is returning false:

class Solution {
    public boolean isPalindrome(String s) {
        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char curr = s.charAt(i);
            if ((curr <= 57 && curr >= 48) || (curr >= 97 && curr <= 122) || (curr <= 90 && curr >= 65)) {
                curr = Character.toLowerCase(curr);
                s1.append(curr);
            }
        }
        s2.append(s1);
        s2.reverse();
        if (s2.equals(s1)) {
            return true;
        }
        return false;
    }
}
4

There are 4 best solutions below

0
Andrej Istomin On

This part of your code is the problem:

if(s2.equals(s1)) {
    return true;
}

What you are doing here is comparing two StringBuilder objects, and they are obviously always different. What you should to instead is to compare the Strings that are build using those builders. To get the string from the builder you need to use toString method. So, your code should look like that:

if(s2.toString().equals(s1.toString())) {
    return true;
}

I've tested your code with this change and it works correctly now. I hope it helps.

1
Zahid Khan On

Change

if(s2.equals(s1)) {
      return true;
}

to

if (s2.compareTo(s1) == 0) {
      return true;
 }
0
DevilsHnd - 退した On

You could simplify the whole process by using a Regular Expression passed to the String#replaceAll() method, for example:

class Solution {
    public boolean isPalindrome(String s) {
        String regEx = "\\p{Punct}|\\s+";
        return s.replaceAll(regEx, "").equalsIgnoreCase(
                new StringBuilder(s).reverse().toString().replaceAll(regEx, ""));
    }
}

What does the used Regular Expression mean?

  • \\p{Punct} All punctuation and special characters;
  • | OR;
  • \\s+ Any white-space character (equivalent to: \r (Carraige Return), \n (Newline or Linefeed), \t (Tab), \f (Formfeed), etc) one or unlimited times.
0
k314159 On

You can circumvent the problem of missing StringBuilder.equals by not using it. Instead, you can directly compare characters of the filtered string:

public static boolean isPalindrome(String s) {
    var filtered = s.codePoints()
            .filter(Character::isLetterOrDigit)
            .map(Character::toLowerCase)
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append);
    var length = filtered.length();
    return IntStream.range(0, length / 2)
            .allMatch(i -> filtered.codePointAt(i) == filtered.codePointAt(length - 1 - i));
}