文章目录
跟随carl代码随想录刷题
语言:python
242. 简单
有效的字母异位词
题目:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的
字母异位词
。
注意:若 s 和 t 中每个字符出现的次数都相同
,则称 s 和 t 互为字母异位词。
示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false
题目分析
- 选定所用的数据结构:数组?set?map?
- 因为本题中所有组成元素都是小写字母,而我们已知:
- 小写字母共有26个 ->
哈希值比较小
, - 小写字母
a-z
的ASCII码是连续 ->范围可控
- 小写字母共有26个 ->
- 所以选择
数组
- 因为本题中所有组成元素都是小写字母,而我们已知:
- 本题涉及计算ASCII码值。python中用于计算ASCII码值的函数是
ord()
- 数组的范围可以设计为
0-25
,可根据ord(s[i]) - ord('a')
得到元素的相对索引,采用小写字母的相对索引来存储。- eg:
s[i] = 'a'
时,ord(s[i]) - ord('a') = 0
- eg:
s[i] = 'z'
时,ord(s[i]) - ord('a') = 25
- eg:
- 可以通过遍历第一个字符串,得到记录对应元素个数的数组
record
。 - 然后遍历第二个字符串,在
record
数组的基础上,减去相应字母的个数 - 如果最后
record
数组有元素不为0,说明两个字符串不是字母异位词,反之则是。
完整代码如下
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
"""
数据结构的选取:
由题意可以知道,本题元素都为小写字母,且a-z的ASCII码是连续的,所以用数组
"""
record = [0]*26 # 初始化一个数组
for i in range(len(s)):
record[ord(s[i]) - ord('a')] += 1
for i in range(len(t)):
record[ord(t[i]) - ord('a')] -= 1
for i in range(26):
if record[i] != 0:
return False
return True
383. 简单
赎金信
题目:给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
.
如果可以,返回 true ;否则返回 false 。
.
magazine 中的每个字符只能在 ransomNote 中使用一次。
题目分析
思路与上一题很像,唯一的区别就是对record
数组的判别条件:
- 本题中:当字符串
magazine
中的元素个数≥
字符串ransomNote
中的元素个数时,返回True
- 即:当记录完
magazine
中的元素个数,得到数组record
之后,再相应地减去randomNote
中的相应元素。如果record
数组中出现负数,则说明magazine中的元素个数少于ransomNote中的元素个数,返回False,否则返回True。
完整代码如下
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
record = [0]*26
for i in range(len(magazine)):
record[ord(magazine[i]) - ord('a')] += 1
for i in range(len(ransomNote)):
record[ord(ransomNote[i]) - ord('a')] -= 1
for i in range(26):
if record[i] < 0:
return False
return True
补充知识:python赋值与拷贝
- python直接赋值是对地址的引用
新变量 = 老变量
,即对老变量起别名。新老变量同时指向同一片内存,对新变量所做的任何修改都会连带修改老变量。 - 若不想让新变量的操作影响老变量,就需要使用拷贝,即
新变量 = 老变量.copy()
a = [1,1,1]
b = a
for i in range(3):
b[i] += 1
print(f'a = {a}')
print(f'b = {b}')
# 输出:
# a = [2, 2, 2]
# b = [2, 2, 2]
49. 中等
字母异位词分组
题目:给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
待学……
438. 中等
找到字符串中所有字母异位词
题目:给定两个字符串
s
和p
,找到s
中所有p
的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词
指由相同字母重排列形成的字符串(包括相同的字符串)。
👉示例 1:
输入: s = “cbaebabacd”, p = “abc”
输出: [0,6]
解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的异位词。
👉示例 2:
输入: s = “abab”, p = “ab”
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 “ab”, 它是 “ab” 的异位词。
起始索引等于 1 的子串是 “ba”, 它是 “ab” 的异位词。
起始索引等于 2 的子串是 “ab”, 它是 “ab” 的异位词。
题目分析
注意:图中的x
是删除
的意思。
完整代码如下
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
s_len, p_len = len(s), len(p)
if s_len < p_len:
return []
ans = []
s_count = [0] * 26
p_count = [0] * 26
for i in range(p_len):
s_count[ord(s[i]) - 97] += 1
p_count[ord(p[i]) - 97] += 1
if s_count == p_count:
ans.append(0)
# 窗口移动
for i in range(s_len - p_len):
s_count[ord(s[i]) - 97] -= 1 # 清除第i位的内容
s_count[ord(s[i + p_len]) - 97] += 1 # 添加第i+p_len位的内容
if s_count == p_count:
ans.append(i + 1)
return ans