学习网址:https://datawhalechina.github.io/leetcode-notes/#/ch03/index.md
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s
,如果它是 回文串 ,返回 true
;否则,返回 false
。
示例 1:
输入: s = "A man, a plan, a canal: Panama" 输出:true 解释:"amanaplanacanalpanama" 是回文串。
示例 2:
输入:s = "race a car" 输出:false 解释:"raceacar" 不是回文串。
示例 3:
输入:s = " " 输出:true 解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。 由于空字符串正着反着读都一样,所以是回文串。
class Solution(object):
def isPalindrome(self, s):
"""
:type s: str
:rtype: bool
"""
# 第一步:创建新字符串,去除字符串中的非字母数字字符
new_s = ''
# 遍历s中的每个字符
for c in s:
# 检测字符c是否为字母或数字
if c.isalnum():
# 如果是字母或数字,则添加到新字符串中
new_s += c
# 将过滤后的字符串赋值给s
s = new_s
# 第二步:将字符串转换为小写
s = s.lower()
# 第三步:使用双指针法判断回文
# 初始化左指针left为0,右指针right为字符串长度减1
left, right = 0, len(s) - 1
# 当左指针小于右指针时,循环进行以下判断
while left < right:
# 如果左指针和右指针所指的字符不相等,则不是回文,返回False
if s[left] != s[right]:
return False
# 如果相等,则左指针右移,右指针左移,继续比较下一对字符
left += 1
right -= 1
# 如果循环结束都没有返回False,则说明字符串是回文,返回True
return True
给定一个字符串 s
,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入:s = "Let's take LeetCode contest" 输出:"s'teL ekat edoCteeL tsetnoc"
示例 2:
输入: s = "Mr Ding" 输出:"rM gniD"
提示:
1 <= s.length <= 5 * 104
s
包含可打印的 ASCII 字符。s
不包含任何开头或结尾空格。s
里 至少 有一个词。s
中的所有单词都用一个空格隔开。
class Solution(object):
def reverseString(self, s):
"""
:type s: List[str]
:rtype: None Do not return anything, modify s in-place instead.
"""
# 反向输出数组即可
s.reverse()
给定一个字符串 s
,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入:s = "Let's take LeetCode contest" 输出:"s'teL ekat edoCteeL tsetnoc"
示例 2:
输入: s = "Mr Ding" 输出:"rM gniD"
提示:
1 <= s.length <= 5 * 104
s
包含可打印的 ASCII 字符。s
不包含任何开头或结尾空格。s
里 至少 有一个词。s
中的所有单词都用一个空格隔开。
class Solution(object):
def reverseWords(self, s):
"""
:type s: str
:rtype: str
"""
# 输入:Mr Ding
# 使用空格来分割每一个单词
words = s.split(' ')
# 输出:['Mr', 'Ding']
# 反转每一个单词
reversed_words = [word[::-1] for word in words]
# 输出:['rM', 'gniD']
# 将反转后的单词用空格连接起来
return ' '.join(reversed_words)
# 输出:rM gniD
给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
示例 1:
输入:haystack = "sadbutsad", needle = "sad" 输出:0 解释:"sad" 在下标 0 和 6 处匹配。 第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:
输入:haystack = "leetcode", needle = "leeto" 输出:-1 解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
提示:
1 <= haystack.length, needle.length <= 104
haystack
和needle
仅由小写英文字符组成-
给定一个非空的字符串
s
,检查是否可以通过由它的一个子串重复多次构成。示例 1:
输入: s = "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba" 输出: false
示例 3:
输入: s = "abcabcabcabc" 输出: true 解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
提示:
1 <= s.length <= 104
s
由小写英文字母组成-
class Solution(object): def repeatedSubstringPattern(self, s): """ :type s: str :rtype: bool """ ''' ,我们尝试将字符串 s 重复一次,然后去掉首尾各一个字符,看剩下的字符串是否包含原始字符串 s。如果包含,那么原始字符串 s 就是由它的一个子串重复多次构成的。 ''' # 将字符串 s 重复一次,然后去掉首尾各一个字符 double_s = (s + s)[1:-1] # 检查剩下的字符串是否包含原始字符串 s return s in double_s
给定一个非空的字符串
s
,检查是否可以通过由它的一个子串重复多次构成。示例 1:
输入: s = "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba" 输出: false
示例 3:
输入: s = "abcabcabcabc" 输出: true 解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
提示:
1 <= s.length <= 104
s
由小写英文字母组成
class Solution(object):
def repeatedSubstringPattern(self, s):
"""
:type s: str
:rtype: bool
"""
'''
,我们尝试将字符串 s 重复一次,然后去掉首尾各一个字符,看剩下的字符串是否包含原始字符串 s。如果包含,那么原始字符串 s 就是由它的一个子串重复多次构成的。
'''
# 将字符串 s 重复一次,然后去掉首尾各一个字符
double_s = (s + s)[1:-1]
# 检查剩下的字符串是否包含原始字符串 s
return s in double_s
给定两个字符串 a
和 b
,寻找重复叠加字符串 a
的最小次数,使得字符串 b
成为叠加后的字符串 a
的子串,如果不存在则返回 -1
。
注意:字符串 "abc"
重复叠加 0 次是 ""
,重复叠加 1 次是 "abc"
,重复叠加 2 次是 "abcabc"
。
示例 1:
输入:a = "abcd", b = "cdabcdab" 输出:3 解释:a 重复叠加三遍后为 "abcdabcdabcd", 此时 b 是其子串。
示例 2:
输入:a = "a", b = "aa" 输出:2
示例 3:
输入:a = "a", b = "a" 输出:1
示例 4:
输入:a = "abc", b = "wxyz" 输出:-1
class Solution(object):
def repeatedStringMatch(self, a, b):
"""
:type a: str
:type b: str
:rtype: int
"""
# 首先计算a重复叠加的次数,应该是b的长度除以a的长度的商
times = len(b) // len(a)
# 如果有余数,说明还需要再叠加一次
if len(b) % len(a) != 0:
times += 1
# 生成a重复叠加times次的字符串
combined_str = a * times
# 检查b是否是combined_str的子串
if b in combined_str:
return times
else:
# 如果不是,再多叠加一次,再次检查
combined_str += a
if b in combined_str:
return times + 1
else:
return -1
先读题,写注释分布完成,然后再想想注释里的步骤应该怎样实现。
暴力搜索(Brute Force)、拉宾-卡普(Rabin Karp)算法、Knuth-Morris-Pratt(KMP)算法后,每种算法都有其适用场景和优势。
暴力搜索直观易懂,但效率较低;Rabin-Karp利用滚动哈希提高多模式搜索效率;KMP算法通过预处理避免了回溯,高效地处理单模式匹配问题。