字符串

  • 1629. 按键持续时间最长的键
  • 2027. 转换字符串的最少操作次数
  • 344. 反转字符串
  • 434. 字符串中的单词数
    • 方法一:split
    • 方法二:
  • 1332. 删除回文子序列
  • 1816. 截断句子
  • 8. 字符串转换整数 (atoi)
    • 方法一:
    • 方法二: re
  • 1576. 替换所有的问号
  • 383. 赎金信
  • 748. 最短补全词
  • 345. 反转字符串中的元音字母
  • 306. 累加数
  • 2011. 执行操作后的变量值
  • 第二部分
  • 686. 重复叠加字符串匹配
  • 2109. 向字符串添加空格
  • 481. 神奇字符串
  • 第三部分
  • 1614. 括号的最大嵌套深度
  • 71. 简化路径
  • 541. 反转字符串 II
  • 796. 旋转字符串
    • 方法一:穷举法
    • 方法二:判断子串
  • 806. 写字符串需要的行数
  • 859. 亲密字符串
  • 917. 仅仅反转字母
  • 925. 长按键入
  • 1047. 删除字符串中的所有相邻重复项
  • 1221. 分割平衡字符串
  • 1370. 上升下降字符串
  • 1417. 重新格式化字符串
  • 1446. 连续字符
  • 1528. 重新排列字符串
    • 方法一:模拟
  • 1544. 整理字符串
    • 方法一:模拟
  • 1662. 检查两个字符串数组是否相等
  • 1684. 统计一致字符串的数目
  • 1768. 交替合并字符串
    • 方法一:
    • 方法二:队列,zip_longest
  • 1790. 仅执行一次字符串交换能否使两个字符串相等
  • 1796. 字符串中第二大的数字
  • 1957. 删除字符使字符串变好
  • 1967. 作为子字符串出现在单词中的字符串数目
  • 2000. 反转单词前缀
  • 30. 串联所有单词的子串
  • 205. 同构字符串
  • 438. 找到字符串中所有字母异位词
    • 49. 字母异位词分组
    • 242. 有效的字母异位词
    • 1347. 制造字母异位词的最小步骤数
  • 387. 字符串中的第一个唯一字符
    • 方法一:dict
    • 方法二:find rfind
    • 方法三:set
  • 2063. 所有子字符串中的元音
    • 方法一:对偶性质
    • 方法二:动态规划
  • 面试题 01.06. 字符串压缩
  • 3. 无重复字符的最长子串
    • 方法一:滑动窗口
    • 方法二:find
    • 方法三
    • 方法四
    • 方法五
  • 97. 交错字符串

1629. 按键持续时间最长的键

Leetcode

class Solution:def slowestKey(self, releaseTimes: List[int], keysPressed: str) -> str:res = keysPressed[0]maxTime = releaseTimes[0]for i in range(1, len(keysPressed)):key = keysPressed[i]delta = releaseTimes[i] - releaseTimes[i - 1]if delta > maxTime:   res = keymaxTime = deltaelif delta == maxTime:res = max(res, key)return res

2027. 转换字符串的最少操作次数

Leetcode

class Solution:def minimumMoves(self, s: str) -> int:res, i, n = 0, 0, len(s)while i < n:if s[i] == "X":res += 1i += 3else: i += 1return res

344. 反转字符串

Leetcode

class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""# i, j = 0, len(s)-1# while i < j:#     s[i], s[j] = s[j], s[i]#     i += 1#     j -= 1 for i in range(len(s)//2):s[i], s[len(s) - 1 - i] = s[len(s) - 1 - i], s[i]# s[:] = s[::-1]

434. 字符串中的单词数

Leetcode

方法一:split

class Solution:def countSegments(self, s: str) -> int:return len(s.split())

方法二:

class Solution:def countSegments(self, s: str) -> int:res = 0for i, c in enumerate(s):if (i == 0 or s[i-1] == ' ') and c != ' ':res += 1return res

1332. 删除回文子序列

Leetcode

class Solution:def removePalindromeSub(self, s: str) -> int:return 1 if s == s[::-1] else 2

1816. 截断句子

Leetcode

class Solution:def truncateSentence(self, s: str, k: int) -> str:# for i in range(len(s)):            #     if s[i] == ' ':k -= 1#     if k == 0:return s[:i]# return sw = s.split()      return ' '.join(w[:k])

8. 字符串转换整数 (atoi)

Leetcode
知识点: isdigit strip

方法一:

class Solution:def myAtoi(self, s: str) -> int:s = s.strip()if s == '': return 0x, tmp, flag = 0, '', -1 if s[0] == '-' else 1# 去掉符号位# if s[0] == '-' or s[0] == '+': s = s[1:]if s[0] in ['-','+']: s = s[1:]for c in s:if not c.isdigit(): breaktmp += cif tmp:x = int(tmp) * flagx = min(max(x, -2**31), 2**31 - 1)return x

方法二: re

class Solution:def myAtoi(self, s: str) -> int:# *args 和 **kwargs 不定长参数,re.findall 结果是列表作为解包提供给 intreturn max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)

1576. 替换所有的问号

Leetcode
**知识点:**哨兵

class Solution:def modifyString(self, s: str) -> str:res, n = list(s), len(s)# res = ['*'] + list(s) + ['*'] # 添加哨兵for i, c in enumerate(res):if c == '?':                 for ch in 'abc': # 三个总有一个符合条件if (i == 0 or ch != res[i - 1]) and (i == n - 1 or ch != res[i + 1]):# if ch != res[i - 1] and ch != res[i + 1]:res[i] = chbreakreturn ''.join(res) # return ''.join(res[1:-1])

383. 赎金信

Leetcode

class Solution:def canConstruct(self, ransomNote: str, magazine: str) -> bool:c1 = collections.Counter(ransomNote)c2 = collections.Counter(magazine)x = c1 - c2# x 只保留值大于0的键,# x 只保留下了,magazine 不够的return len(x) == 0

748. 最短补全词

Leetcode

class Solution:def shortestCompletingWord(self, licensePlate: str, words: List[str]) -> str:words.sort(key=len)res  = ""minlen = inflp = Counter(c.lower() for c in licensePlate if c.isalpha())for word in words:#n = len(word)#if n < minlen and not lp - Counter(word):#res = word#minlen = nif not lp - Counter(word):return word#return res# cnt = Counter(ch.lower() for ch in licensePlate if ch.isalpha())# return min((word for word in words if not cnt - Counter(word)), key=len)

345. 反转字符串中的元音字母

Leetcode

class Solution:def reverseVowels(self, s: str) -> str:vowel = 'aeiouAEIOU'l, r, t = 0, len(s)-1, list(s)while l < r:while l < r and t[l] not in vowel: l += 1while l < r and t[r] not in vowel: r -= 1       t[l], t[r] = t[r], t[l]l += 1r -= 1return ''.join(t)class Solution:def reverseVowels(self, s: str) -> str:m = [e for e in s if e in 'aeiouAEIOU']return ''.join([m.pop() if x in 'aeiouAEIOU' else x for x in s])

306. 累加数

Leetcode

class Solution:def isAdditiveNumber(self, num: str) -> bool:n = len(num)for i in range(1, n - 1):for j in range(i + 1, n):first, second, third = 0, i, j # 三个数的起点while third < n:# 前两个数有前导 0,或者第三个数不够长。if (num[first] == '0' and second - first > 1) or (num[second] == '0' and third - second > 1) or n - third < third - second:breaks = str(int(num[first:second]) + int(num[second:third]))# if s != num[third:third + len(s)]:                    if not num.startswith(s, third): # str.startswith(prefix[, start[, end]])breakfirst, second, third = second, third, third + len(s)else:return Truereturn False

2011. 执行操作后的变量值

Leetcode

class Solution:def finalValueAfterOperations(self, operations: List[str]) -> int:x = 0for i in operations:# if i in ["++X", "X++"]:# if '+' in i:#     x += 1# else:#     x -= 1x += 1 if '+' in i else -1return x# return sum(1 if  "+" in op else -1 for op in operations)

第二部分

686. 重复叠加字符串匹配

Leetcode
如果 a 不是 b 的子串并且 b 由 a 的前后两部分组成,则只需要两个 a 即可。
如:“abc” “ca” -> “abcabc” 即 x + 1,此时 x = 1
如果 a 是 b 的子串并且 b 的两端(或一端)可以组成 a,那么只需要最多拆分一个 a。
如:“abc” “abcabc” 不用拆分 a ; “abc” “cabca” b 两端拆分一个 a。即 x,此时 x >= 1
否则的话返回 -1

剪枝 如果 b 中包含有不在 a 中的字符,返回 -1

class Solution:def repeatedStringMatch(self, a: str, b: str) -> int:# 剪枝 如果 b 中包含有不在 a 中的字符,返回 -1if set(b) - set(a): return -1x = ceil(len(b) / len(a))for i in [x, x + 1]:if (a*i).find(b) != -1: return ireturn -1

2109. 向字符串添加空格

Leetcode

class Solution:def addSpaces(self, s: str, spaces: List[int]) -> str:       res = s[:spaces[0]]for i in range(1, len(spaces)):res += ' ' + s[spaces[i-1]:spaces[i]]res += ' ' + s[spaces[-1]:]return res

481. 神奇字符串

Leetcode

class Solution:def magicalString(self, n: int) -> int:        x = ['1','2','2']tmp = '1' # 1 和 2 交替for i in range(2, n): # 从第三个数开始生成           x.extend(tmp * int(x[i]))       tmp = '2' if tmp == '1' else '1'if len(x) > n:break # 剪枝return ''.join(x)[:n].count('1')# s, c = '122', '1'# for i in range(2, n):#     s += c * int(s[i])           #     c = chr(ord(c)^3) # 1, 2 交替#     if len(s) > n:break# return s[:n].count('1')

第三部分

1614. 括号的最大嵌套深度

Leetcode

class Solution:def maxDepth(self, s: str) -> int:res, k, q = 0, 0, []for ch in s:if ch == '(':k += 1res = max(res, k)q.append(ch)if ch == ')':k -= 1q.pop()return res

71. 简化路径

Leetcode

class Solution:def simplifyPath(self, path: str) -> str:res = []for p in path.split("/"):if p == "..":res and res.pop()elif p and p != ".":res.append(p)return "/" + "/".join(res)

541. 反转字符串 II

Leetcode

class Solution:def reverseStr(self, s: str, k: int) -> str:t = list(s)for i in range(0, len(s), 2*k):t[i:i+k] = reversed(t[i:i+k])return ''.join(t)return ''.join([s[i:i+k][::-1] if i%(2*k) == 0 else s[i:i+k] for i in range(0, len(s), k)])

例:

s='abcdefghijklab'
t = list(s)
k=3for i in range(0, len(s), 2*k):t[i:i+k]=t[i:i+k][::-1]print(t)
# ['c', 'b', 'a', 'd', 'e', 'f', 'i', 'h', 'g', 'j', 'k', 'l', 'b', 'a']
# i 是 k 的整数倍,奇数倍反转、偶数倍原样。
[s[i:i+k] if i%(2*k) else s[i:i+k][::-1] for i in range(0, len(s), k)]
# ['cba', 'def', 'ihg', 'jkl', 'ba']

796. 旋转字符串

Leetcode
知识点: find,True,False,all,%

方法一:穷举法

class Solution:def rotateString(self, s: str, goal: str) -> bool:m, n = len(s), len(goal)if m != n:  return False        if m == 0:  return True# if s == goal: return Truefor i in range(n):# if all(s[(i+j) % n] == goal[j] for j in range(n)):#     return True s = s[1:] + s[0]if s == goal: return Truereturn False

方法二:判断子串

先判断长度是否相同,不相同返回 False,其次拼接两个 s,则如果 goal 是由 s 旋转而成,则拼接后的 s 一定包含 goal。

class Solution:def rotateString(self, s: str, goal: str) -> bool:# if len(s) != len(goal): return False# return goal in s * 2# return len(s) == len(goal) and (s * 2).find(goal) != -1     return len(s) == len(goal) and goal in s * 2

806. 写字符串需要的行数

Leetcode

class Solution:def numberOfLines(self, widths: List[int], s: str) -> List[int]:lines, width = 1, 0for c in s:w = widths[ord(c)-ord("a")]width += wif width > 100:lines += 1width = wreturn [lines, width]

859. 亲密字符串

Leetcode

class Solution:def buddyStrings(self, s: str, goal: str) -> bool:m, n = len(s), len(goal)if m != n: return Falseif s == goal: return len(set(s)) != n # 有重复字母为真tmp = [[x, y] for x, y in zip(s, goal) if x != y]if len(tmp) != 2: return Falsereturn tmp[0] == tmp[1][::-1]

917. 仅仅反转字母

Leetcode
知识点: list isalpha join 推导式 pop 交换元素

class Solution:def reverseOnlyLetters(self, s: str) -> str:'''x = list(s)i, j = 0, len(s)-1while i < j:a, b = x[i].isalpha(),x[j].isalpha()if not a:  i += 1if not b:  j -= 1if a and b:x[i], x[j] = x[j], x[i]i += 1j -= 1return "".join(x)    ''' # 栈先进后出res = [c for c in s if c.isalpha()]ans = ""        for c in s:if c.isalpha():ans += res.pop()else:ans += creturn ans

925. 长按键入

Leetcode

class Solution:def isLongPressedName(self, name: str, typed: str) -> bool:m, n = len(typed), len(name)i, j = 0, 0while i < m:if j < n and typed[i] == name[j]:i += 1;j += 1                 elif i > 0 and typed[i] == typed[i-1]: i += 1# (i == 0 or typed[i] != typed[i-1]) and typed[i] == name[j]else: return False  # j = 0# for i in range(m): #     if j < n and typed[i] == name[j]:#         j += 1              #     elif i == 0 or typed[i] != typed[i-1]:#         return False  return j == n

1047. 删除字符串中的所有相邻重复项

Leetcode

class Solution:def removeDuplicates(self, s: str) -> str:'''      i = 1        while i < len(s):if i > 0 and s[i] == s[i-1]:s = s[:i-1] + s[i+1:]i -= 2i += 1return s'''# 方法二:使用双指针模拟栈res = list(s)slow = fast = 0n = len(res)# while fast < n:#     # 如果一样直接换,不一样会把后面的填在 slow 的位置#     res[slow] = res[fast]#     # 如果发现和前一个一样,就退一格指针#     if slow > 0 and res[slow] == res[slow - 1]:#         slow -= 1#     else:#         slow += 1#     fast += 1for i in range(n):res[slow] = res[i]if slow > 0 and res[slow] == res[slow-1]:slow -= 1else:slow += 1return ''.join(res[:slow])'''# 方法三:栈x = []for c in s:# if not x or c != x[-1]:#     x.append(c)   # else:#     x.pop()if x and c == x[-1]:x.pop()else:x.append(c)return ''.join(x)'''

1221. 分割平衡字符串

Leetcode

class Solution:def balancedStringSplit(self, s: str) -> int:res = d = 0for ch in s:d += (1 if ch == "R" else -1)if d == 0: res += 1return res

1370. 上升下降字符串

Leetcode

class Solution:def sortString(self, s: str) -> str:cnt, res, d = 0, '', defaultdict(int)for c in s: d[c] += 1        x = sorted(d)while x:res += ''.join(x)cnt += 1# x = [c for c in x[::-1] if d[c] - cnt > 0]x = [x[i] for i in range(len(x)-1, -1, -1) if d[x[i]] - cnt > 0]return res

1417. 重新格式化字符串

Leetcode

class Solution:def reformat(self, s: str) -> str:        nums, string, res = [], [], ''for c in s:if c.isdigit(): nums.append(c)else: string.append(c)m, n = len(string), len(nums)if abs(m - n) > 1:return ""if m > n:for i in range(n):res += string[i] + nums[i]res += string[-1]else:for i in range(m):res += nums[i] + string[i]if m < n:res += nums[-1]return res

1446. 连续字符

Leetcode

class Solution:def maxPower(self, s: str) -> int:## # res = tmp = 1# x = s[0]# for i in range(1, len(s)):#     if s[i] == x:#         tmp += 1#     else:#         res = max(res, tmp)#         x = s[i]#         tmp = 1# return max(res, tmp)## 双指针res, slow, n = 1, 0, len(s)for i in range(1, n):if s[i] != s[slow]:res = max(res, i - slow)slow = ires = max(res, n - slow) return res

1528. 重新排列字符串

Leetcode

方法一:模拟

定义一个数组,长度为 len(s);循环(循环变量 i),填充数组;将 indices[i] 为索引,s[i] 填充。
将列表用""连接并返回。

class Solution:def restoreString(self, s: str, indices: List[int]) -> str:res = [''] * len(s)# for i, j in enumerate(indices):       #     res[j] = s[i]for i, c in enumerate(s):res[indices[i]] = creturn ''.join(res)

1544. 整理字符串

Leetcode

方法一:模拟

知识点: list,lower,append,pop,join,split,ord,chr。
教程:

从左到右扫描字符串 s 的每个字符。扫描过程中,维护当前整理好的字符串,记为 res。当扫描到字符 ch 时,有两种情况:

字符 ch 与字符串 res 的最后一个字符互为同一个字母的大小写:根据题意,两个字符都要在整理过程中被删除,因此要弹出 res 的最后一个字符;否则:两个字符都需要被保留,因此要将字符 ch 附加在字符串 res 的后面。

判断两个字母是否是互为大小写:

res[-1].lower() == ch.lower() and res[-1] != ch # 方法一
abs(ord(res[-1]) - ord(ch)) == 32: # 方法二:大小写字母 ASCII 值相差 32
ord(ch) ^ 32 == ord(res[-1]) # 方法三:运用异或判断是否互为大小写 ord('a') ^ 32 = ord('A'); ord('A') ^ 32 = ord('a');

ord() 函数是 chr() 函数(对于 8 位的 ASCII 字符串)的配对函数,它以一个字符串(Unicode 字符)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值。

ord("中") # 20013
chr(20013) # '中'
class Solution:def makeGood(self, s: str) -> str:res = list()for ch in s:# if res and res[-1].lower() == ch.lower() and res[-1] != ch:# if res and abs(ord(res[-1]) - ord(ch)) == 32: # 大小写字母 ASII 值相差 32if res and ord(ch) ^ 32 == ord(res[-1]):            res.pop()else:res.append(ch)return "".join(res)

1662. 检查两个字符串数组是否相等

Leetcode

class Solution:def arrayStringsAreEqual(self, word1: List[str], word2: List[str]) -> bool:# w1 = ''.join(word1)# w2 = ''.join(word2)# return w2 == w1return ''.join(word1) == ''.join(word2)

1684. 统计一致字符串的数目

Leetcode

class Solution:def countConsistentStrings(self, allowed: str, words: List[str]) -> int:res = 0for w in words:for c in w:if c not in allowed:break            else:res += 1return res

1768. 交替合并字符串

Leetcode

方法一:

class Solution:def mergeAlternately(self, word1: str, word2: str) -> str:x, res = min(len(word1), len(word2)), ''for i in range(x):        res += word1[i] + word2[i]res += word1[x:] + word2[x:]   # 处理剩余的部分     return res

方法二:队列,zip_longest

class Solution:def mergeAlternately(self, word1: str, word2: str) -> str:# a, b = deque(word1), deque(word2)# res = ""# while a and b:#     res += a.popleft()#     res += b.popleft()# res += "".join(a) + "".join(b)# return res# from  itertools import zip_longestreturn "".join(sum(zip_longest(word1, word2, fillvalue=""), ()))

1790. 仅执行一次字符串交换能否使两个字符串相等

Leetcode

class Solution:def areAlmostEqual(self, s1: str, s2: str) -> bool:first = second = Falsefor i, c in enumerate(s1):if s2[i] != c:if not first: # 第一次不同,记录下来。first = Truex = s2[i]y = celif not second: # 第二次不同if c != x or s2[i] != y:return Falsesecond = Trueelse:return Falsereturn not first or (first and second)
class Solution:def areAlmostEqual(self, s1: str, s2: str) -> bool:if sorted(s1) != sorted(s2): return Falsefirst = second = Truefor i, c in enumerate(s1):if s2[i] != c:if first:first = Falseelif second:second = Falseelse:return Falsereturn True

1796. 字符串中第二大的数字

Leetcode

class Solution:def secondHighest(self, s: str) -> int:# 方法一:# res = first = second = -1# for c in s:#     if c.isdigit():#         d = int(c)#         if d > first:#             first, second = d, first#         else:#             if first > d > second:#                 second = d# return second# 方法二:list sort# digit = []# for c in s:#     if c.isdigit() and int(c) not in digit:#         digit.append(int(c))# digit.sort()# return digit[-2] if len(digit) > 1 else -1# 方法三:filter list sort map 高阶函数digit = sorted(map(int, set(filter(str.isdigit, s))))  # 过滤英文字母return digit[-2] if len(digit) > 1 else -1

1957. 删除字符使字符串变好

Leetcode
知识点: 字符串(索引、切片、长度),len,!=,+=,in (not in) ,or 和 for。
教程:Python 1-09 字符串

class Solution:def makeFancyString(self, s: str) -> str:# n = len(s)# if n < 3: return sres = s[:2]for c in s[2:]:if c != res[-1] or c != res[-2]:res += creturn res

1967. 作为子字符串出现在单词中的字符串数目

Leetcode

class Solution:def numOfStrings(self, patterns: List[str], word: str) -> int:# res = 0# for w in patterns:#     if w in word:#         res += 1# return resreturn sum(w in word for w in patterns) # sum 可统计逻辑值 True 的个数

2000. 反转单词前缀

Leetcode

class Solution:def reversePrefix(self, word: str, ch: str) -> str:idx = word.find(ch)return word[:idx+1][::-1] + word[idx+1:] if idx != -1 else word

30. 串联所有单词的子串

Leetcode

class Solution:def findSubstring(self, s: str, words: List[str]) -> List[int]:## 方法一:全排列 超时# n = len(words)# res = []# for p in permutations(words, n):   #     i = "".join(p)        #     idx = -1#     while True:#         idx = s.find(i, idx + 1)#         if idx == -1:break#         res.append(idx)# return list(set(res))## 方法二:Counterfrom collections import Counterres = []wordLen = len(words[0])totalLen = len(words) * wordLenn = len(s)words = Counter(words)for i in range(n - totalLen + 1):sub = s[i:i + totalLen] # 依次截取总长子串,移动窗口。tmp = [sub[j:j + wordLen] for j in range(0, totalLen, wordLen)] # 切割总子串为等长子串if Counter(tmp) == words: # 单词与个数都相同,正好匹配。res.append(i)return res

205. 同构字符串

Leetcode

class Solution:def isIsomorphic(self, s: str, t: str) -> bool:s2t = {}t2s = {}for i in range(len(s)):if s2t.get(s[i], t[i]) != t[i] or t2s.get(t[i], s[i]) != s[i]:return Falses2t[s[i]] = t[i]t2s[t[i]] = s[i]return True# return all(s.index(s[i]) == t.index(t[i])  for i in range(len(s)))

438. 找到字符串中所有字母异位词

Leetcode

class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:n, w = len(s), len(p)if n < w: return []ans = []d = defaultdict(int)for i in range(w):d[s[i]] += 1d[p[i]] -= 1if not any(d.values()):ans.append(0)for i in range(w,  n):           d[s[i - w]] -= 1 # 滑动窗口d[s[i]] += 1if not any(d.values()):ans.append(i - w + 1)return ans

49. 字母异位词分组

Leetcode

class Solution:def groupAnagrams(self, strs: List[str]) -> List[List[str]]:      d = defaultdict(list)for s in strs:x = "".join(sorted(s))d[x].append(s)return list(d.values())

242. 有效的字母异位词

Leetcode

class Solution:def isAnagram(self, s: str, t: str) -> bool:return Counter(s) == Counter(t)# return ''.join(sorted(s)) == ''.join(sorted(t))

1347. 制造字母异位词的最小步骤数

Leetcode

class Solution:def minSteps(self, s: str, t: str) -> int:x = Counter(s)for ch in t:x[ch] -= 1  return sum(v for v in x.values() if v > 0)

387. 字符串中的第一个唯一字符

Leetcode

方法一:dict

class Solution:def firstUniqChar(self, s: str) -> int:# d = defaultdict(int)# for c in s:#     d[c] += 1d = collections.Counter(s)for i, c in enumerate(s):if d[c] == 1:return ireturn -1

方法二:find rfind

class Solution:def firstUniqChar(self, s: str) -> int:for i, c in enumerate(s):if s.find(c) == s.rfind(c):return ireturn -1

方法三:set

class Solution:def firstUniqChar(self, s: str) -> int:seen = set()for i, c in enumerate(s):if s.rfind(c) == i and c not in seen:return ielse:seen.add(c)return -1

2063. 所有子字符串中的元音

Leetcode

方法一:对偶性质

「所有子串中的元音的总数」,等价于「串中每一个元音,包含它的子串个数」的和。

遍历 word,如果第 i 个字符是元音,那么包含它的子串的左端点可以选择 0, 1, ⋯, i 一共 i + 1 种,右端点可以选择 i, i + 1, ⋯, n − 1 一共 n - i 种(n = len(word) ),因此包含它的子串个数为 (i + 1)(n - i)。

class Solution:def countVowels(self, word: str) -> int:n = len(word)vowels, res = "aeiou", 0for i, ch in enumerate(word):if ch in vowels:res += (i + 1) * (n - i)return res

方法二:动态规划

f[i] 表示以字符 word[i] 结尾的子串的元音数量
转移方程:
f[i] = f[i - 1] + (i + 1 if word[i] 是元音 else 0)
返回:sum(f)

class Solution:def countVowels(self, word: str) -> int:vowel, n = 'aeiou', len(word)dp = [0] * nif word[0] in vowel: dp[0] = 1 for i in range(1, n):dp[i] = dp[i - 1] +  (i + 1 if word[i] in vowel else 0)return sum(dp)

简化

class Solution:def countVowels(self, word: str) -> int:res = a = 0for i in range(len(word)):           a += (i + 1 if word[i] in 'aeiou' else 0) res += areturn res

面试题 01.06. 字符串压缩

Leetcode

class Solution:def compressString(self, S: str) -> str:# n, res, i = len(S), '', 0# while i < n:#     j = i#     while j < n and S[j] == S[i]:#         j += 1#     res += S[i] + str(j - i)#     i = jif not S: return Stmp, cnt, res = S[0], 0, ''for c in S:if c == tmp:cnt += 1else:res += tmp + str(cnt)tmp, cnt = c, 1res += tmp + str(cnt)return res if len(res) < len(S) else S

3. 无重复字符的最长子串

Leetcode
知识点: 字典 滑动窗口 find

方法一:滑动窗口

class Solution:def lengthOfLongestSubstring(self, s: str) -> int:       d = {} # element:index ,element 的位置# subStr = '' # 记录最长不重复子串left = ans = 0for i, c in enumerate(s): # if c in subStr: # 发现有重复字符时,# if c in d: # d 包含子串前面的字符,此方法不正确if c in s[left: i]:# 直接把左指针移到第一个重复字符后面。只能针对 s,不能是 subStr            left = d[c] + 1else:ans = max(ans, i - left + 1)# subStr = s[left: i + 1]d[c] = i # 记录 c 元素位置,注意重复字符会被更新return ans

方法二:find

class Solution:def lengthOfLongestSubstring(self, s: str) -> int:       subStr, ans = '', 0       for c in s: if c in subStr: # 发现有重复字符时,subStr = subStr[subStr.find(c) + 1:]      else:           ans = max(ans, len(subStr) + 1)        subStr += creturn ans

方法三

class Solution:def lengthOfLongestSubstring(self, s: str) -> int:    ans = left = 0for i, c in enumerate(s):       if c in s[left: i]:left += s[left:i].find(c) + 1     else: ans = max(ans, i - left + 1)      return ans

方法四

class Solution(object):def lengthOfLongestSubstring(self, s: str) -> int: ans = left = 0for i, c in enumerate(s):   index = s[left: i].find(c) # 在子串(切片)中查找 c,不包含当前 c,找不到为 -1 if index != -1:left += index + 1 # 注意 index 是切片中的索引,所以要加偏移量 left,下一个元素 + 1else: ans = max(ans, i - left + 1) # 找不到 + 1,i 增加了 1return ans

方法五

class Solution(object):def lengthOfLongestSubstring(self, s: str) -> int: d={}   ans = left = 0for i, c in enumerate(s):   if c in s[left: i]:left = d[c] + 1else:ans = max(ans, i - left + 1) d[c] = ireturn ans

97. 交错字符串

Leetcode
定义 f(i, j) 表示 s1 的前 i 个元素和 s2 的前 j 个元素是否能交错组成 s3 的前 i + j 个元素。
转移方程:

f(i,j)=[f(i−1,j)ands1(i−1)=s3(p)]or[f(i,j−1)ands2(j−1)=s3(p)]f(i, j) = [f(i - 1, j) \, {\rm and} \, s_1(i - 1) = s_3(p)] \, {\rm or} \, [f(i, j - 1) \, {\rm and} \, s_2(j - 1) = s_3(p)]f(i,j)=[f(i−1,j)ands1​(i−1)=s3​(p)]or[f(i,j−1)ands2​(j−1)=s3​(p)]
其中 p = i + j - 1。
边界条件为 f(0, 0) = True

class Solution:def isInterleave(self, s1: str, s2: str, s3: str) -> bool:m, n = len(s1), len(s2)if m + n != len(s3): return Falsedp = [[False]*(n + 1) for _ in range(m + 1)]dp[0][0] = Truefor i in range(m):dp[i+1][0] = dp[i][0] and s1[i] == s3[i]for j in range(n):dp[0][j+1] = dp[0][j] and s2[j] == s3[j]for i in range(m):for j in range(n):p = i + j + 1dp[i+1][j+1] = dp[i+1][j] and s2[j] == s3[p] or dp[i][j+1] and s1[i] == s3[p]return dp[-1][-1]
class Solution:def isInterleave(self, s1: str, s2: str, s3: str) -> bool:m, n = len(s1), len(s2)if m + n != len(s3): return Falsedp = [False] * (n + 1)dp[0] = Truefor i in range(m + 1):for j in range(n + 1):p = i + j - 1if i > 0:dp[j] = dp[j] and s1[i - 1] == s3[p]if j > 0:dp[j] = dp[j] or dp[j - 1] and s2[j - 1] == s3[p]return dp[n]

Leetcode str相关推荐

  1. web前端技术练习题

    选择题 1.以下哪个不属于Web前端开发的核心技术?(   ). A.HTML C.JavaScript B.CSS D.Java 2.关于HTML说法错误的是(   ). A.HTML标签的嵌套结构 ...

  2. LeetCode #1349. 参加考试的最大学生数 - 学到了:压缩状态动态规划、位运算、reduce()、str().count()

    赛题见:https://leetcode-cn.com/problems/maximum-students-taking-exam/ 我的解法是用递归实现广度优先搜索,结果是对的,但是太慢,超时了.这 ...

  3. leetcode 5. Longest Palindromic Substring 字符串中的最长回文数 逐步从O(n^2)优化至线性时间

    题目 解析 思路一 暴力解法 思路二 指针+最大长度 思路3 由中间至两边找回数 思路4 Manacher's algorithm 线性时间 参考文档 题目 链接 给定一个字符串 s,找到 s 中最长 ...

  4. LeetCode简单题之删除字符使字符串变好

    题目 一个字符串如果没有 三个连续 相同字符,那么它就是一个 好字符串 . 给你一个字符串 s ,请你从 s 删除 最少 的字符,使它变成一个 好字符串 . 请你返回删除后的字符串.题目数据保证答案总 ...

  5. LeetCode简单题之整理字符串

    题目 给你一个由大小写英文字母组成的字符串 s . 一个整理好的字符串中,两个相邻字符 s[i] 和 s[i+1],其中 0<= i <= s.length-2 ,要满足如下条件: 若 s ...

  6. LeetCode简单题之Excel 表中某个范围内的单元格

    题目 Excel 表中的一个单元格 (r, c) 会以字符串 "" 的形式进行表示,其中: 即单元格的列号 c .用英文字母表中的 字母 标识. 例如,第 1 列用 'A' 表示, ...

  7. LeetCode简单题之数组中的字符串匹配

    题目 给你一个字符串数组 words ,数组中的每个字符串都可以看作是一个单词.请你按 任意 顺序返回 words 中是其他单词的子字符串的所有单词. 如果你可以删除 words[j] 最左侧和/或最 ...

  8. LeetCode简单题之解码字母到整数映射

    题目 给你一个字符串 s,它由数字('0' - '9')和 '#' 组成.我们希望按下述规则将 s 映射为一些小写英文字符: 字符('a' - 'i')分别用('1' - '9')表示. 字符('j' ...

  9. LeetCode简单题之最长特殊序列 Ⅰ

    题目 给你两个字符串 a 和 b,请返回 这两个字符串中 最长的特殊序列 .如果不存在,则返回 -1 . 「最长特殊序列」 定义如下:该序列为 某字符串独有的最长子序列(即不能是其他字符串的子序列) ...

  10. LeetCode简单题之字符的最短距离

    题目 给你一个字符串 s 和一个字符 c ,且 c 是 s 中出现过的字符. 返回一个整数数组 answer ,其中 answer.length == s.length 且 answer[i] 是 s ...

最新文章

  1. Unity3D中使用KiiCloud总结一
  2. 抽象工厂模式-与-工厂方法模式区别
  3. 《数据库SQL实战》从titles表获取按照title进行分组
  4. OpenCL “速成”冲刺【第一天】
  5. python datetime处理时间
  6. 常用的几款抓包工具_ 常见的4种抓包工具比较
  7. R语言入门-安装R和Rstuido软件
  8. 5.4、聚类之EM聚类实例
  9. 悟空CRM系统学习心得
  10. STM32 之十 供电系统及内部参照电压(VREFINT)使用及改善ADC参考电压,内部参照电压的具体方法,只有在STM32F0x芯片的参考手册中才能找到,其他MCU的参考手册都是很简单的说明
  11. 插空排序C语言(直接插入排序)
  12. 蓝字冲销是什么意思_红字和蓝字冲销
  13. 摄像头poe供电原理_poe供电是什么_poe供电工作原理介绍 - 全文
  14. 某酷ckey签名生成算法系列--(三)ast代码控制流平坦化
  15. 【ESP32教程】ESP32EEPROM的使用(使用示例中的eeprom class用法)
  16. 安装和简单使用visual studio 2017
  17. 自制最小的linux系统下载, 自制小型Linux系统
  18. nuc970 网络问题排查过程
  19. raid读写速度对比_RAID5和RAID1的读写速度对比大概是多少
  20. C语言——文件操作(2)文件的读写操作

热门文章

  1. HTML标签的连续的英文折断英文连续不换行英文字符溢出
  2. 情人节程序员用HTML网页表白【情人节爱你的代码】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
  3. android入门之Activity 后台启动限制
  4. 一个让Google、Facebook、Amazon都羡慕的平台,为什么说阿里妈妈是数字营销的未来...
  5. 功能安全-三种确认措施报告之安全评估报告学习记录
  6. [2019 icpc徐州] H.Yuuki and a problem 带修改的主席树(主席树+树状数组)
  7. css3箭头水平淡入淡出
  8. 计算机显卡型号中数字含义详解,显卡型号中字母和数字所代表的含义.doc
  9. 阿里云压缩包无法分享解决方案
  10. [Chatter] 错误处理的安全保证等级