Skip to content

Latest commit

 

History

History
228 lines (182 loc) · 5.32 KB

125.Valid_Palindrome.md

File metadata and controls

228 lines (182 loc) · 5.32 KB
  1. Valid Palindrome 难度 简单

A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.

Given a string s, return true if it is a palindrome, or false otherwise.

Example 1:

Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.

Example 2:

Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.

Example 3:

Input: s = " "
Output: true

Explanation: s is an empty string "" after removing non-alphanumeric characters.
Since an empty string reads the same forward and backward, it is a palindrome.
 

Constraints:

1 <= s.length <= 2 * 105
s consists only of printable ASCII characters.

相关企业 半年内半年 ~ 1年1年 ~ 2年 Facebook|54 微软 Microsoft|11 苹果 Apple|4 彭博 Bloomberg|3

相关标签 Two Pointers String

相似题目 Palindrome Linked List 简单 Valid Palindrome II 简单

note

  • 大思路一样
  • 处理很多corner case
  • 需要辅助函数

slove version

  • 2 pointer, check left and right char, move towards middle
  • deal with corner cases len <= 1, non letters string
  • corner case, "a.", "1p", ".p" (key is which if of 3 if in while is the last exec block)
  • Note: alphanumeric include digit
class Solution {
    public boolean isPalindrome(String s) {
        if (s == null || s.length() == 0){
            return false;
        }else if (s.length() == 1){
            return true;
        }
        
        int left = 0;
        int right = s.length() - 1;
        while(left < right){
            if (!isLetterOrDigit(Character.toLowerCase(s.charAt(left)))){
                left ++;
                continue;
            }
            if (left == s.length()){ // for non letters string
                return true; 
            }
            if (!isLetterOrDigit(Character.toLowerCase(s.charAt(right)))){
                right --;
                continue;
            }

            if ( Character.toLowerCase(s.charAt(left)) == Character.toLowerCase(s.charAt(right)) ){
                left ++;
                right --;
            }else{
                return false;
            }   
        }
        if (left - right == 1){
            return true;
        }else if (left == right){
            return true;
        }
        return false;
    }

    public boolean isLetterOrDigit(char c){
        return Character.isLetter(c) || Character.isDigit(c);
    }
}

faster

  • faster bc using while inside while loop for some cases
public class Solution {
   /**
    * @param s: A string
    * @return: Whether the string is a valid palindrome
    */
   public boolean isPalindrome(String s) {
       // write your code here
       if (s == null || s.length() == 0){
           return true;
       }
      
       int left = 0;
       int right = s.length() - 1;
      
       while (left < right){
           // only check invalid condition
          
           while (left < s.length() && ! isValid(s.charAt(left)) ){
               left ++;
           }
          
           if (left == s.length()){
               return true; //for non letters string
           }
          
           while (right >= 0 && !isValid(s.charAt(right))){
               right --;
           }
          
           if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right)) ){
               break;
           }else {
               left ++;
               right --;
           }
       }
       return left >= right;
   }
  
   private boolean isValid(char c){
       return Character.isLetter(c) || Character.isDigit(c);
   }
}

no need check non-letter string

  • return directly
public class Solution {
   /**
    * @param s: A string
    * @return: Whether the string is a valid palindrome
    */
   public boolean isPalindrome(String s) {
       // write your code here
       if (s == null || s.length() == 0){
           return true;
       }
      
       int left = 0;
       int right = s.length() - 1;
      
       while (left < right){
           // only check invalid condition
          
           while (left < right && ! isValid(s.charAt(left)) ){
               left ++;
           }
          
           while (left < right && !isValid(s.charAt(right))){
               right --;
           }
          
           if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right)) ){
               return false;
           }else {
               left ++;
               right --;
           }
       }
       return true;
   }
  
   private boolean isValid(char c){
       return Character.isLetter(c) || Character.isDigit(c);
   }
}
class Solution:
    def isPalindrome(self, s: str) -> bool:
        if not s:
            return False

        left, right = 0, len(s) - 1
        while left < right:
            while left < right and not s[left].isalpha() and not s[left].isdigit():
                left += 1
            while left < right and not s[right].isalpha() and not s[right].isdigit():
                right -= 1

            if s[left].lower() == s[right].lower():
                left += 1
                right -= 1
            else:
                return False
        
        return True