【LeetCode 热题 100】438. 找到字符串中所有字母异位词 | python 【中等】

继续学!嗨起来!!!(正确率已经下30%了,我在干什么)

题目:

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

给定两个字符串 sp,找到 s中所有 p的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

示例 1:

复制代码
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

注意:

  1. 是异位词
  2. 要求时间短
  3. 滑动窗口解法(类似双指针)

不熟悉的操作:

[0]*26 = np.zeros([1,26])

ord() 是 Python 的内置函数,用于获取字符的 ASCII 码值

标准解法:

1.将p的字母和数量储存起来,滑动窗口

不用每次排序

不是用字典储存,而是一个列表,从a到z存字母个数【天才想法!】

一些思考:如果用字典呢?不过字典还要搜索,但如果不在就可以跳过(跟为负跳过是一样的捏)

里面的数据不用遍历:移过则出,没过则进

python 复制代码
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
            s_count[ord(s[i + p_len]) - 97] += 1
            
            if s_count == p_count:
                ans.append(i + 1)

        return ans

作者:力扣官方题解
链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/solutions/1123971/zhao-dao-zi-fu-chuan-zhong-suo-you-zi-mu-xzin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2.减小储存空间,出相同-1,进相同+1,differ记录不同的个数

部分代码:

python 复制代码
# 列表推导式的结果:生成一个布尔值列表,表示每个元素是否是非零值。
count = [1, 0, 2, 0, 3]
bool_list = [c != 0 for c in count]
print(bool_list)  # 输出:[True, False, True, False, True]

# .count(True):计算布尔值列表中 True 的数量,即非零元素的数量。
differ = bool_list.count(True)
print(differ)  # 输出:3

全部代码:

python 复制代码
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 = []
        count = [0] * 26
        for i in range(p_len):
            count[ord(s[i]) - 97] += 1
            count[ord(p[i]) - 97] -= 1

        differ = [c != 0 for c in count].count(True)

        if differ == 0:
            ans.append(0)

        for i in range(s_len - p_len):
            if count[ord(s[i]) - 97] == 1:  # 窗口中字母 s[i] 的数量与字符串 p 中的数量从不同变得相同
                differ -= 1
            elif count[ord(s[i]) - 97] == 0:  # 窗口中字母 s[i] 的数量与字符串 p 中的数量从相同变得不同
                differ += 1
            count[ord(s[i]) - 97] -= 1

            if count[ord(s[i + p_len]) - 97] == -1:  # 窗口中字母 s[i+p_len] 的数量与字符串 p 中的数量从不同变得相同
                differ -= 1
            elif count[ord(s[i + p_len]) - 97] == 0:  # 窗口中字母 s[i+p_len] 的数量与字符串 p 中的数量从相同变得不同
                differ += 1
            count[ord(s[i + p_len]) - 97] += 1
            
            if differ == 0:
                ans.append(i + 1)

        return ans

作者:力扣官方题解
链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/solutions/1123971/zhao-dao-zi-fu-chuan-zhong-suo-you-zi-mu-xzin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

自己的做法:

O(N2Logn),因为排序,时间比较长

又是用双指针做的,感觉和滑动窗口异曲同工(不过双指针中间长度不固定,滑动窗口固定罢了)

感觉我丢return 【】的这部分丢的比它做法1多

**写代码的时候出现的问题:**for循环的数量和缩进

python 复制代码
class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        # 想法1:把所有p的排列组合列出来,进行搜索
        # 想法2:把所有有字母的对应长度截取下来排序,看看和p是否不同
        # 想法2的拓展:把每个字母都在p(集合)内的同等长度序列截下来,再判断
        # 先丢一部分
        s_set = set(s)
        p_set = set(p)
        for x in p_set:
            if x not in s_set:
                return []
        # 双指针
        a = 0
        b = len(p)
        p_sort = sorted(p)
        l = []
        while b <= len(s):
            if s[a] in p_set:
                for x in s[a+1:b]:    # 错1
                    if x not in p_set:
                        break
                if x == s[b-1]:    # 错2
                    l1 = sorted(s[a:b])
                    if l1 == p_sort:
                        l.append(a)
            a += 1
            b += 1
        return l

1. 时间复杂度更高(减了一个判断),但更好懂的代码

python 复制代码
class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        # 想法1:把所有p的排列组合列出来,进行搜索
        # 想法2:把所有有字母的对应长度截取下来排序,看看和p是否不同
        # 想法2的拓展:把每个字母都在p(集合)内的同等长度序列截下来,再判断
        # 先丢一部分
        s_set = set(s)
        p_set = set(p)
        for x in p_set:
            if x not in s_set:
                return []
        # 双指针
        a = 0
        b = len(p)
        p_sort = sorted(p)
        l = []
        while b <= len(s):
            if s[a] in p_set:
                l1 = sorted(s[a:b])
                if l1 == p_sort:
                    l.append(a)
            a += 1
            b += 1
        return l
相关推荐
IT猿手几秒前
2025最新群智能优化算法:海市蜃楼搜索优化(Mirage Search Optimization, MSO)算法求解23个经典函数测试集,MATLAB
开发语言·人工智能·算法·机器学习·matlab·机器人
IT猿手2 小时前
2025最新群智能优化算法:山羊优化算法(Goat Optimization Algorithm, GOA)求解23个经典函数测试集,MATLAB
人工智能·python·算法·数学建模·matlab·智能优化算法
Dream it possible!5 小时前
LeetCode 热题 100_字符串解码(71_394_中等_C++)(栈)
c++·算法·leetcode
修己xj6 小时前
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
算法
开心比对错重要7 小时前
leetcode69.x 的平方根
数据结构·算法·leetcode
美狐美颜sdk7 小时前
什么是美颜SDK?从几何变换到深度学习驱动的美颜算法详解
人工智能·深度学习·算法·美颜sdk·第三方美颜sdk·视频美颜sdk·美颜api
m0_461502697 小时前
【贪心算法1】
算法·贪心算法
Doopny@7 小时前
数字组合(信息学奥赛一本通-1291)
数据结构·算法·动态规划
原来是猿8 小时前
蓝桥备赛(13)- 链表和 list(上)
开发语言·数据结构·c++·算法·链表·list
项目申报小狂人8 小时前
高性能算法NGO!北方苍鹰优化算法(Northern Goshawk Optimization,NGO)
算法·数学建模