我最近在复习OD考试时,汇总了一写字符串的基本算法,方便 OD考试的初学者
from collections import Counter
class Solution(object):
"""
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若s 和 t中每个字符出现的次数都相同,则称s 和 t互为字母异位词
"""
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
return sorted(s) == sorted(t)
"""
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
"""
def groupAnagrams(self, strs):
"""
:type strs: List[str]
:rtype: List[List[str]]
"""
dic = {} # 用字典进行存取
for s in strs: # 对每个字符串进行遍历
keys = "".join(sorted(s)) # 对字符串进行正序排列
print(keys)
if keys not in dic: # 只有一个的情况
dic[keys] = [s] # 要记得带中括号,否则下面不能使用append(),而且最后的输出也需要。
else: # 多个的情况
dic[keys].append(s)
print(dic[keys])
print(dic)
print(dic.values())
print(list(dic.values()))
"""
给定两个字符串s和 p,找到s中所有p的异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指由相同字母重排列形成的字符串(包括相同的字符串)
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
"""
def findAnagrams(self, s, p):
p_count = Counter(p) # 对字符串p中的字符进行计数
s_count = Counter(s[:len(p) - 1]) # 对字符串s中前len(p)个字符进行计数
ans = [] # 结果列表,用于保存s中p的易位词出现位置
for i in range(len(p) - 1, len(s)): # 从p的长度开始遍历到s的长度
# s[i]从右边进入滑动窗口
s_count[s[i]] += 1 # 更新字符计数器s_count中s[i]的出现次数
cur_idx = i - len(p) + 1 # 滑动窗口左端元素在s中的位置
cur_char = s[cur_idx] # 滑动窗口左端元素
# 易位词判别,比较窗口中字符串s[cur_idx:i]和目标字符串p是否互为易位词
if s_count == p_count:
ans.append(cur_idx) # 如果是,则将滑动窗口左端位置加入到结果列表中
s_count[cur_char] -= 1 # 将滑动窗口左端元素从窗口中弹出,更新字符计数器
if s_count[cur_char] == 0: # 如果弹出后计数器中出现次数变为零
del s_count[cur_char] # 从计数器中删除该字符
return ans
"""
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个回文串 。
输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串
"""
def isPalindrome(self, s: str) -> bool:
s_new = ''.join(i.lower() for i in s if i.isalnum())
return s_new[::-1] == s_new
"""
给你一个字符串 s,最多 可以从中删除一个字符。请你判断 s 是否能成为回文字符串:如果能,返回 true ;否则,返回 false
输入:s = "abca"
输出:true
解释:你可以删除字符 'c'
输入:s = "abc"
输出:false
"""
def validPalindrome(self, s: str) -> bool:
l, r = 0, len(s) - 1
while l <= r:
if s[l] == s[r]:
l += 1
r -= 1
else:
j_1 = s[l + 1:r + 1] # 删掉左边不等的进行判断,r+1是因为当前r代表的指针也是为判断的字符需要包含在内
j_2 = s[l:r] # 删掉右边不等的进行判断
return j_1 == j_1[::-1] or j_2 == j_2[::-1]
return 1 == 1
"""
给你一个字符串 s,找到 s 中最长的回文子串
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
"""
def maxPalindromeString(sele,s):
maxnum = 0
if len(s) <= 2:
return len(s), s
for start in range(len(s)):
for end in range(start + 1, len(s)):
if end + 1 <= len(s) + 1 and s[start:end + 1] == s[start:end + 1][::-1]:
if len(s[start:end + 1]) >= maxnum:
maxnum = len(s[start:end + 1])
palindrome = s[start:end + 1]
return maxnum, palindrome