哈希表 | 有效字母异位词 | 用`数组`做最合适 | leecode刷题笔记

跟随carl代码随想录刷题
语言:python


242. 简单有效的字母异位词

题目:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false

题目分析

  1. 选定所用的数据结构:数组?set?map?
    • 因为本题中所有组成元素都是小写字母,而我们已知:
      • 小写字母共有26个 -> 哈希值比较小
      • 小写字母a-z的ASCII码是连续 -> 范围可控
    • 所以选择数组
  2. 本题涉及计算ASCII码值。python中用于计算ASCII码值的函数是ord()
  3. 数组的范围可以设计为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
  4. 可以通过遍历第一个字符串,得到记录对应元素个数的数组record
  5. 然后遍历第二个字符串,在record数组的基础上,减去相应字母的个数
  6. 如果最后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赋值与拷贝

  1. python直接赋值是对地址的引用新变量 = 老变量,即对老变量起别名。新老变量同时指向同一片内存,对新变量所做的任何修改都会连带修改老变量。
  2. 若不想让新变量的操作影响老变量,就需要使用拷贝,即新变量 = 老变量.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. 中等找到字符串中所有字母异位词

题目:给定两个字符串 sp,找到 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值