LeetCode 125. Validate palindrome string

Title Description

Given a string, verify whether it is a palindrome string. Only alphanumeric characters are considered, and the case of letters can be ignored.

Note: in this topic, we define an empty string as a valid palindrome string.

Example:

Input: "A man, a plan, a canal: Panama" output: true
Explanation: "Amana planacanalpanama" is a palindrome string

Method 1: screening + judgment

The simplest way is to traverse the string s once, and keep the alphanumeric characters in it and put them in another string sgood. In this way, we only need to judge whether sgood is an ordinary palindrome string.

There are two ways to judge. The first is to use the string flipping API in the language to get the reverse order string sgood of sgood_rev, as long as the two strings are the same, sgood is the palindrome string.

C++

class Solution {
public:
    bool isPalindrome(string s) {
        string sgood;
        for (char ch: s) {
            if (isalnum(ch)) {
                sgood += tolower(ch);
            }
        }
        string sgood_rev(sgood.rbegin(), sgood.rend());
        return sgood == sgood_rev;
    }
};

Java

class Solution {
    public boolean isPalindrome(String s) {
        StringBuffer sgood = new StringBuffer();
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char ch = s.charAt(i);
            if (Character.isLetterOrDigit(ch)) {
                sgood.append(Character.toLowerCase(ch));
            }
        }
        StringBuffer sgood_rev = new StringBuffer(sgood).reverse();
        return sgood.toString().equals(sgood_rev.toString());
    }
}

Python

class Solution:
    def isPalindrome(self, s: str) -> bool:
        sgood = "".join(ch.lower() for ch in s if ch.isalnum())
        return sgood == sgood[::-1]

Method 2: double pointer

Initially, the left and right pointers point to both sides of the sgood respectively. Then we continuously move the two pointers one step at a time, and judge whether the characters pointed to by the two pointers are the same. When the two pointers meet, it indicates that sgood is a palindrome string.

C++

class Solution {
public:
    bool isPalindrome(string s) {
        string sgood;
        for (char ch: s) {
            if (isalnum(ch)) {
                sgood += tolower(ch);
            }
        }
        int n = sgood.size();
        int left = 0, right = n - 1;
        while (left < right) {
           if (sgood[left] != sgood[right]) {
                return false;
            }
            ++left;
            --right;
        }
        return true;
    }
};

Java

class Solution {
    public boolean isPalindrome(String s) {
        StringBuffer sgood = new StringBuffer();
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char ch = s.charAt(i);
            if (Character.isLetterOrDigit(ch)) {
                sgood.append(Character.toLowerCase(ch));
            }
        }
        int n = sgood.length();
        int left = 0, right = n - 1;
        while (left < right) {
            if (Character.toLowerCase(sgood.charAt(left)) != Character.toLowerCase(sgood.charAt(right))) {
                return false;
            }
            ++left;
            --right;
        }
        return true;
    }
}

Python

class Solution:
    def isPalindrome(self, s: str) -> bool:
        sgood = "".join(ch.lower() for ch in s if ch.isalnum())
        n = len(sgood)
        left, right = 0, n - 1
        
        while left < right:
            if sgood[left] != sgood[right]:
                return False
            left, right = left + 1, right - 1
        return True

Complexity analysis

  • Time complexity: O(∣ s ∣), where ∣ s ∣ is the length of string s.
  • Spatial complexity: O(∣ s ∣). Because we need to store all alphabetic and numeric characters in another string, in the worst case, the new string sgood is exactly the same as the original string s, so we need to use the space of O(∣ s ∣).

optimization

Direct judgment on the original string

We can optimize the second method of judging palindrome string in method 1, and we can get an algorithm that only uses O(1) space.

We use double pointers directly on the original string s. When moving any pointer, you need to constantly move in the direction of the other pointer until you encounter an alphabetic or numeric character, or the two pointers coincide. That is, each time we move the pointer to the next alphabetic character or numeric character, we judge whether the characters pointed to by the two pointers are the same.

class Solution {
    public boolean isPalindrome(String s) {
        int n = s.length();
        int left = 0, right = n - 1;
        while (left < right) {
            while (left < right && !Character.isLetterOrDigit(s.charAt(left))) {
                ++left;
            }
            while (left < right && !Character.isLetterOrDigit(s.charAt(right))) {
                --right;
            }
            if (left < right) {
                if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {
                    return false;
                }
                ++left;
                --right;
            }
        }
        return true;
    }
}

Complexity analysis

  • Time complexity: O(∣ s ∣), where ∣ s ∣ is the length of string s.

  • Space complexity: O(1).

come on.

thank!

strive!

Tags: Java Algorithm leetcode

Posted on Tue, 12 Oct 2021 13:48:04 -0400 by seanpaulcail