给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: “A man, a plan, a canal: Panama”
输出: true
解释:“amanaplanacanalpanama” 是回文串
示例 2:
输入: “race a car”
输出: false
解释:“raceacar” 不是回文串
基础:1-4
题解:5,6,7
1.Python isalpha()方法:
Python isalpha() 方法检测字符串是否只由字母组成。
如果字符串至少有一个字符并且所有字符都是字母则返回 True,否则返回 False。
例:
str = "leetcode"
print(str.isalpha())
str1 = "leetcode12"
print(str1.isalpha())
str2 = "leetcode12...."
print(str2.isalpha())
输出为:
True
False
False
2.Python isdigit()方法
Python isdigit() 方法检测字符串是否只由数字组成。
如果字符串只包含数字则返回 True 否则返回 False。
例:
str = "123456" # Only digit in this string
print(str.isdigit())
str = "this is string example....wow!!!"
print(str.isdigit())
输出为:
True
False
3.Python lower()方法
Python lower() 方法转换字符串中所有大写字符为小写。
4.ans[::-1]的意思
演示一下,秒懂起来。
import numpy as np
a=np.random.rand(5)
print(a)
[ 0.64061262 0.8451399 0.965673 0.89256687 0.48518743]
print(a[-1]) ###取最后一个元素
[0.48518743]
print(a[:-1]) ### 除了最后一个取全部
[ 0.64061262 0.8451399 0.965673 0.89256687]
print(a[::-1]) ### 取从后向前(相反)的元素
[ 0.48518743 0.89256687 0.965673 0.8451399 0.64061262]
print(a[2::-1]) ### 取从下标为2的元素翻转读取
[ 0.965673 0.8451399 0.64061262]
5.题解一
含数字 字母 空格 符号,只考虑数字&字母 -> alnum()
遍历+判断
时间:o(n)
空间:o(n)
class Solution:
def isPalindrome(self, s: str) -> bool:
ans = []
s = s.lower()
for i in s:
if i.isalpha() or i.isdigit():
ans.append(i)
return ans == ans[::-1]
调试:
class Solution:
def isPalindrome(self, s: str) -> bool:
print('输入s:', s)
ans = []
print('当前ans为:', ans)
s = s.lower() # 大写转小写
print('s:', s)
for i in s:
print('i=' + i + '时:')
print('i.isalpha():', i.isalpha())
print('i.isdigit():', i.isdigit())
if i.isalpha() or i.isdigit():
ans.append(i)
print('此时ans:', ans)
return ans == ans[::-1]
if __name__ == '__main__':
s = Solution()
re = s.isPalindrome("A man, a plan, a canal: Panama")
print(re)
输出:
输入s: A man, a plan, a canal: Panama
当前ans为: []
s: a man, a plan, a canal: panama
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a']
i= 时:
i.isalpha(): False
i.isdigit(): False
i=m时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm']
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a']
i=n时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n']
i=,时:
i.isalpha(): False
i.isdigit(): False
i= 时:
i.isalpha(): False
i.isdigit(): False
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a']
i= 时:
i.isalpha(): False
i.isdigit(): False
i=p时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p']
i=l时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l']
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a']
i=n时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n']
i=,时:
i.isalpha(): False
i.isdigit(): False
i= 时:
i.isalpha(): False
i.isdigit(): False
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a']
i= 时:
i.isalpha(): False
i.isdigit(): False
i=c时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c']
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a']
i=n时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n']
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a']
i=l时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l']
i=:时:
i.isalpha(): False
i.isdigit(): False
i= 时:
i.isalpha(): False
i.isdigit(): False
i=p时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'p']
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'p', 'a']
i=n时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'p', 'a', 'n']
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'p', 'a', 'n', 'a']
i=m时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'p', 'a', 'n', 'a', 'm']
i=a时:
i.isalpha(): True
i.isdigit(): False
此时ans: ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'p', 'a', 'n', 'a', 'm', 'a']
True
6.题解二
筛选+双指针
时间:o(n)
空间:o(n)—>新增了一个e=[]
(1)Python isalnum()方法
符合题意中的“只考虑字母和数字字符”
–Python isalnum() 方法检测字符串是否由字母和数字组成。
注意:–如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
str = "this2009"; # 字符中没有空格
print(str.isalnum())
>>True
(2)pyhton (for in if)用法
这个人讲的不错,点击查看
(3)题解
class Solution:
def isPalindrome(self, s: str) -> bool:
s = [ch.lower() for ch in s if ch.isalnum()]
l,r = 0,len(s)-1 # 初始化双指针
while l < r: # 有效条件
if s[l] != s[r]:return False # 双指针判断
l,r = l+1,r-1 # 更新双指针
return True
(4)调试
这条语句:
s = [ch.lower() for ch in s if ch.isalnum()]
等价于:
e = []
for ch in s:
ch = ch.lower()
# print(ch)
if ch.isalnum():
e.append(ch)
例:测试"Ab man, a plan, a canal: Panama",应该返回False。
测试"A man, a plan, a canal: Panama",应该返回True。
class Solution:
def isPalindrome(self, s: str) -> bool:
# s = [ch.lower() for ch in s if ch.isalnum()]这句话啥意思呀,这么长?\
e = []
for ch in s:
ch = ch.lower()
# print(ch)
if ch.isalnum():
e.append(ch)
print(e)
# s = [ch.lower() for ch in s if ch.isalnum()]
# print(s)
l, r = 0, len(e) - 1 # 初始化双指针
# l = 0
# r = len(e) -1
print('len(e) -1:',len(e) -1)
print('初始值l和r分别为:', 'l=', l, 'r=', r)
while l < r: # 有效条件
print('e[l]:', e[l])
print('e[r]:', e[r])
if e[l] != e[r]:
return False # 双指针判断
l, r = l + 1, r - 1 # 更新双指针
print('此时的l=', l)
print('此时的r=', r)
return True
if __name__ == '__main__':
s = Solution()
re = s.isPalindrome("Ab man, a plan, a canal: Panama")
print(re)
输出为:
['a', 'b', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'p', 'a', 'n', 'a', 'm', 'a']
len(e) -1: 21
初始值l和r分别为: l= 0 r= 21
e[l]: a
e[r]: a
此时的l= 1
此时的r= 20
e[l]: b
e[r]: m
False
文字题解:
1.首先遍历每一个字母,将大写字母转为小写字母,把不符合数字和字符的忽略,不append进e=[];
2.前后各定义一个指针,分别从前后开始比较是否相同;
3.如果相同,则前指针右移一位,后指针左移一位,继续遍历,直到l < r,结束;
4.如果不相同,则直接False,表示不是回文字符串。
7.题解三
空间o(1)解法,在原字符串上修改,先判断判断是否为数字or字母,之后再判断相等是否回文
时间:o(n)
空间:o(1)–>都在s[]中操作
(1)题解三
class Solution:
def isPalindrome(self, s: str) -> bool:
l,r = 0,len(s)-1
while l < r:
while l < r and not s[l].isalnum(): l += 1
while l < r and not s[r].isalnum(): r -= 1
if l < r:
if s[l].lower() != s[r].lower():return False
l,r = l+1,r-1
return True
(2)对比题解二
class Solution:
def isPalindrome(self, s: str) -> bool:
s = [ch.lower() for ch in s if ch.isalnum()]
l,r = 0,len(s)-1 # 初始化双指针
while l < r: # 有效条件
if s[l] != s[r]:return False # 双指针判断
l,r = l+1,r-1 # 更新双指针
return True
说明:题解二中的“s = [ch.lower() for ch in s if ch.isalnum()]”与题解三中的‘while’表达的意思相同。
(3)调试:
class Solution:
def isPalindrome(self, s: str) -> bool:
l, r = 0, len(s) - 1
while l < r:
print('当前l为:', l)
print('当前r为:', r)
print('当前s[l]为:', s[l])
print('当前s[r]为:', s[r])
print('当前s[l].isalnum():', s[l].isalnum())
print('当前s[r].isalnum():', s[r].isalnum())
while l < r and not s[l].isalnum():
l += 1
while l < r and not s[r].isalnum():
r -= 1
if l < r:
if s[l].lower() != s[r].lower():
return False
l, r = l + 1, r - 1
return True
if __name__ == '__main__':
s = Solution()
re = s.isPalindrome("A man, a plan, a canal: Panama")
print(re)
输出为:
当前l为: 0
当前r为: 29
当前s[l]为: A
当前s[r]为: a
当前s[l].isalnum(): True
当前s[r].isalnum(): True
当前l为: 1
当前r为: 28
当前s[l]为:
当前s[r]为: m
当前s[l].isalnum(): False
当前s[r].isalnum(): True
当前l为: 3
当前r为: 27
当前s[l]为: a
当前s[r]为: a
当前s[l].isalnum(): True
当前s[r].isalnum(): True
当前l为: 4
当前r为: 26
当前s[l]为: n
当前s[r]为: n
当前s[l].isalnum(): True
当前s[r].isalnum(): True
当前l为: 5
当前r为: 25
当前s[l]为: ,
当前s[r]为: a
当前s[l].isalnum(): False
当前s[r].isalnum(): True
当前l为: 8
当前r为: 24
当前s[l]为:
当前s[r]为: P
当前s[l].isalnum(): False
当前s[r].isalnum(): True
当前l为: 10
当前r为: 23
当前s[l]为: l
当前s[r]为:
当前s[l].isalnum(): True
当前s[r].isalnum(): False
当前l为: 11
当前r为: 20
当前s[l]为: a
当前s[r]为: a
当前s[l].isalnum(): True
当前s[r].isalnum(): True
当前l为: 12
当前r为: 19
当前s[l]为: n
当前s[r]为: n
当前s[l].isalnum(): True
当前s[r].isalnum(): True
当前l为: 13
当前r为: 18
当前s[l]为: ,
当前s[r]为: a
当前s[l].isalnum(): False
当前s[r].isalnum(): True
当前l为: 16
当前r为: 17
当前s[l]为:
当前s[r]为: c
当前s[l].isalnum(): False
当前s[r].isalnum(): True
True
解释:这个循环,首先是判断l < r,然后再 while l < r and not s[l].isalnum(): ,
如果同时满足 l < r 和s[l].isalnum()不为True而为False,则 l加1,
再执行if l
while l < r:
print('当前l为:', l)
print('当前r为:', r)
print('当前s[l]为:', s[l])
print('当前s[r]为:', s[r])
print('当前s[l].isalnum():', s[l].isalnum())
print('当前s[r].isalnum():', s[r].isalnum())
while l < r and not s[l].isalnum():
l += 1
while l < r and not s[r].isalnum():
r -= 1
if l < r:
if s[l].lower() != s[r].lower():
return False
l, r = l + 1, r - 1
return True