Python算法题集_找到字符串中所有字母异位词

news2024/11/19 17:39:46

本文为Python算法题集之一的代码示例

题目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" 的异位词。

提示:

  • 1 <= s.length, p.length <= 3 * 104

  • sp 仅包含小写字母


问题分析

  1. 因p是固定的,所以检查是否为p的异位词可以直接使用数组的字符计数比较即可【p仅含小写字母,因此数组只有26个元素】
  2. 因p长度固定,因此单循环即可遍历字符串
  3. 优化思路
    1. 减少计算
    2. 加快比较

  1. 标准版【循环进行异位词比较】,性能良好,超越89%,标准版的性能就比较高,说明本题可以优化的空间不大

    注意:CheckFuncPerf是我手搓的函数用时和内存占用模块,下载地址在这里:测量函数运行用时、内存占用的代码单元CheckFuncPerf.py以及使用方法
    在这里插入图片描述

    import CheckFuncPerf as cfp
    
    def findAnagrams(s: str, p: str) -> list[int]:
        list_p = [0] * 26
        list_s = [0] * 26
        list_result = []
        for iIdx in range(len(p)):
            list_p[ord(p[iIdx])-ord('a')] += 1
        for iIdx in range(len(s)):
            list_s[ord(s[iIdx])-ord('a')] += 1
            if iIdx < len(p) - 1:
                continue
            if list_s == list_p:
                list_result.append(iIdx - len(p) + 1)
            list_s[ord(s[iIdx-len(p)+1]) - ord('a')] -= 1
        return list_result
    
    s, p = 'cbaebabacd', 'abc'
    result = cfp.getTimeMemoryStr(findAnagrams, s, p)
    print(result['msg'],'执行结果={}'.format(result['result']))
    # 运行结果
    函数 findAnagrams 的运行时间为 0.00 ms;内存使用量为 4.00 KB 执行结果=[0, 6]
    
  2. 优化版【每次判断是否出现未出现在p中的字符,如出现进行跳跃】,性能自由落体,超越42%
    在这里插入图片描述

    这种优化有赖于p的特性,p的长度越长,优化效果越好;反之,因为每个字符都要多一次比较,性能反而会下降

    def findAnagrams_ext1(s: str, p: str) -> list[int]:
        list_p = [0] * 26
        list_s = [0] * 26
        list_result = []
        for iIdx in range(len(p)):
            list_p[ord(p[iIdx])-ord('a')] += 1
        iIdx, ileft = 0, 0
        while iIdx < len(s):
            if p.find(s[iIdx])<0:
                if iIdx<len(p):
                    for jIdx in range(iIdx):
                        list_s[ord(s[jIdx])-ord('a')] = 0
                else:
                    for jIdx in range(len(p)):
                        list_s[ord(s[iIdx-jIdx])-ord('a')] = 0
                iIdx += 1
                ileft = iIdx
                continue
            list_s[ord(s[iIdx])-ord('a')] += 1
            if iIdx < len(p) + ileft - 1:
                iIdx += 1
                continue
            if list_s == list_p:
                list_result.append(iIdx - len(p) + 1)
            list_s[ord(s[iIdx-len(p)+1]) - ord('a')] -= 1
            ileft += 1
            iIdx += 1
        return list_result
        
    s, p = 'cbaebabacd', 'abc'
    result = cfp.getTimeMemoryStr(findAnagrams_ext1, s, p)
    print(result['msg'],'执行结果={}'.format(result['result']))
    # 运行结果
    函数 findAnagrams_ext1 的运行时间为 0.00 ms;内存使用量为 0.00 KB 执行结果=[0, 6]
    
  3. 计算优化版【标准版中,将ord('a')先计算出来,避免每次计算】,性能优异,超越97%
    在这里插入图片描述

    def findAnagrams_iorda(s: str, p: str) -> list[int]:
        iOrda = ord('a')
        list_p = [0] * 26
        list_s = [0] * 26
        list_result = []
        for iIdx in range(len(p)):
            list_p[ord(p[iIdx])-iOrda] += 1
        for iIdx in range(len(s)):
            list_s[ord(s[iIdx])-iOrda] += 1
            if iIdx < len(p) - 1:
                continue
            if list_s == list_p:
                list_result.append(iIdx - len(p) + 1)
            list_s[ord(s[iIdx-len(p)+1]) - iOrda] -= 1
        return list_result
        
    s, p = 'cbaebabacd', 'abc'
    result = cfp.getTimeMemoryStr(findAnagrams_iorda, s, p)
    print(result['msg'],'执行结果={}'.format(result['result']))
    # 运行结果
    函数 findAnagrams_iorda 的运行时间为 0.00 ms;内存使用量为 0.00 KB 执行结果=[0, 6]
    
  4. 优化加强版【优化版中,将ord('a')先计算出来,避免每次计算】,性能一般,超越54%
    在这里插入图片描述

    def findAnagrams_ext1_iorda(s: str, p: str) -> list[int]:
        iOrda = ord('a')
        list_p = [0] * 26
        list_s = [0] * 26
        list_result = []
        for iIdx in range(len(p)):
            list_p[ord(p[iIdx])-iOrda] += 1
        iIdx, ileft = 0, 0
        while iIdx < len(s):
            if p.find(s[iIdx])<0:
                if iIdx<len(p):
                    for jIdx in range(iIdx):
                        list_s[ord(s[jIdx])-iOrda] = 0
                else:
                    for jIdx in range(len(p)):
                        list_s[ord(s[iIdx-jIdx])-iOrda] = 0
                iIdx += 1
                ileft = iIdx
                continue
            list_s[ord(s[iIdx])-iOrda] += 1
            if iIdx < len(p) + ileft - 1:
                iIdx += 1
                continue
            if list_s == list_p:
                list_result.append(iIdx - len(p) + 1)
            list_s[ord(s[iIdx-len(p)+1]) - iOrda] -= 1
            ileft += 1
            iIdx += 1
        return list_result
        
    s, p = 'cbaebabacd', 'abc'
    result = cfp.getTimeMemoryStr(findAnagrams_ext1_iorda, s, p)
    print(result['msg'],'执行结果={}'.format(result['result']))
    # 运行结果
    函数 findAnagrams_ext1_iorda 的运行时间为 0.00 ms;内存使用量为 0.00 KB 执行结果=[0, 6]
    

    一日练,一日功,一日不练十日空

    may the odds be ever in your favor ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1418932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java基础—面向对象OOP—18三大特性:封装、继承与多态

由于本身理解还不是很到位&#xff0c;所以写的很绕&#xff0c;后续待补充优化 1、封装&#xff08;底层&#xff09;&#xff1a;该露的露&#xff0c;该藏的藏 高内聚&#xff1a;类的内部数据操作细节自己完成&#xff0c;不允许外部干涉低耦合&#xff1a;仅暴露少量的方…

休息日的思考与额外题——链表

文章目录 前言链表知识点 一、 92. 反转链表 II二、21. 合并两个有序链表总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划二刷完卡子哥的刷题计划&#xff0c;加油&#xff01; 二刷决定精刷了&#xff0c;于是参加了卡子哥的刷题班&#xff0c;训练…

2023年算法SAO-CNN-BiLSTM-ATTENTION回归预测(matlab)

2023年算法SAO-CNN-BiLSTM-ATTENTION回归预测&#xff08;matlab&#xff09; SAO-CNN-BiLSTM-Attention雪消融优化器优化卷积-长短期记忆神经网络结合注意力机制的数据回归预测 Matlab语言。 雪消融优化器( SAO) 是受自然界中雪的升华和融化行为的启发&#xff0c;开发了一种…

Linux true/false区分

bash的数值代表和其它代表相反&#xff1a;0表示true&#xff1b;非0代表false。 #!/bin/sh PIDFILE"pid"# truenginx进程运行 falsenginx进程未运行 checkRunning(){# -f true表示普通文件if [ -f "$PIDFILE" ]; then# -z 字符串长度为0trueif [ -z &qu…

shell脚本——条件语句

目录 一、条件语句 1、test命令测试条件表达式 2、整数数值比较 3、字符串比较 4、逻辑测试&#xff08;短路运算&#xff09; 5、双中括号 二、if语句 1、 分支结构 1.1 单分支结果 1.2 双分支 1.3 多分支 2、case 一、条件语句 条件测试&#xff1a;判断某需求是…

IP关联是什么?有什么后果?如何防止电商账号因IP关联被封?

在跨境电商的世界里&#xff0c;IP关联给多账号运营的商家带来了挑战。比如&#xff0c;亚马逊IP关联规则的执行对于那些经营多个店铺的卖家来说可能是一个不小的障碍。IP关联的影响不只是限于亚马逊&#xff0c;其他平台如Instagram、Facebook也有类似的机制&#xff0c;在之前…

Note-归一化层和前向源码

本专栏主要是深度学习/自动驾驶相关的源码实现,获取全套代码请参考 目录 简介BN层计算过程参数说明验证问题:bn层前面的cov不需要bia的原因 LN层计算过程参数说明验证问题:transfomer用LN而不是BN的原因 简介 深度学习中常见的归一化层包括批量归一化&#xff08;Batch Norma…

应急响应-流量分析

在应急响应中&#xff0c;有时需要用到流量分析工具&#xff0c;。当需要看到内部流量的具体情况时&#xff0c;就需要我们对网络通信进行抓包&#xff0c;并对数据包进行过滤分析&#xff0c;最常用的工具是Wireshark。 Wireshark是一个网络封包分析软件。网络封包分析软件的…

Redis面试(二)

1.Redis集群了解吗 前面说到了主从同步存在高可用和分布式问题&#xff0c;哨兵机制解决了高可用问题&#xff0c;而集群就是终极方案&#xff0c;一举解决高可用 和分布式问题。 1.数据分区&#xff1a;数据分区或称数据分片是集群最核心的功能&#xff0c;集群将数据分散到…

【人工智能】鲁滨逊归结原理-Python实现

一、实验目的 了解鲁滨逊归结算法原理&#xff0c;利用Python编写程序&#xff0c;实现鲁滨逊归结算法。 二、实验原理 鲁滨逊归结原理又称为消解原理&#xff0c;是鲁滨逊提出的一种证明子句集不可满足性&#xff0c;从而实现定理证明的一种理论及方法。它是机器定理证明的基…

项目解决方案:市小区高清视频监控平台联网整合设计方案(上)

目 录 一、项目需求 1.1业务需求 1.2技术需求 1.3 环境要求 1.3.1 硬件要求 1.3.2 技术服务要求 二、系统设计方案 2.1 视频监控平台基础功能设计 2.2 视频资源及联网设备编码与管理设计 2.2.1 全省现有联网视频资源属性 2.2.2 视频资源编码具体格…

任务修复实例(1)

实例1 任务名&#xff1a;增强防御&#xff08;quest_template.id 8490&#xff09; 涉及的两个数据表分别为 smart_script 和 creature_summon_groups smart_script Reactstate 取值参考源码 UnitDefines.h 的 ReactStates 定义&#xff0c;其中&#xff1a;0为被动&#…

第18章_JDK8-17新特性(下)(新语法结构,API的变化,其它结构变化,小结与展望)

文章目录 第18章_JDK8-17新特性&#xff08;下&#xff09;6. 新语法结构6.1 Java的REPL工具&#xff1a; jShell命令6.2 异常处理之try-catch资源关闭6.3 局部变量类型推断6.4 instanceof的模式匹配6.5 switch表达式6.6 文本块6.7 Record6.8 密封类 7. API的变化7.1 Optional类…

[docker] Docker镜像的创建以及Dockerfile的使用

一、Dokcer镜像的创建 创建镜像有三种方法&#xff0c;分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。 1.1 基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it --name web centos:7 /bin/bash …

Docker 基础篇

目录 一、Docker 简介 1. Docker 2. Linux 容器 3. 传统虚拟机和容器的对比 4. Docker 的作用 5. Docker 的基本组成&#xff08;Docker 三要素&#xff09; 6. Docker 工作原理 7. Docker 架构 8. Docker 下载 二、Docker 安装 1. CentOS Docker 安装 2. CentOS8 …

03 Verilog HDL 语法

Verilog HDL&#xff08;Hardware Description Language&#xff09;是在 C 语言的基础上发展起来的一种硬件描述语言&#xff08;用它可以表示逻辑电路图、逻辑表达式、数字逻辑系统所完成的逻辑功能等&#xff09;具有灵活性高、易学易用等特点。Verilog HDL 可以在较短的时间…

Edius 9.0 下载安装教程,附安装包和工具,轻松解决软件安装

前言 Edius是一款非线性视频编辑软件&#xff0c;它可以帮助用户快速编辑一切&#xff0c;支持更多格式、更多分辨率而无需等待&#xff0c;无论是纪录片还是4K影视制作&#xff0c;软件都能很好的驾驭&#xff0c;是用户最喜欢的后期制作专业工具。 准备工作 1、Win7及以上…

如何做一个合格的产品经理

如何做一个合格的产品经理 如何做一个合格的产品经理 一、了解市场需求 产品经理的核心工作之一是了解市场需求。为了确保产品的成功&#xff0c;你需要密切关注市场动态&#xff0c;了解用户需求&#xff0c;分析竞争对手&#xff0c;并预测未来趋势。通过市场调查、用户访…

第十八回 林冲水寨大并火 晁盖梁山小夺泊-FreeBSD/Ubunut使用ssh的scp传输文件

何涛在得到知府命令后&#xff0c;带领官兵出发前往石碣村捉拿强盗。在接近石碣村时&#xff0c;他们遇到了一些打渔的人&#xff0c;得知阮小五、阮小七两兄弟在湖中居住&#xff0c;非乘船不能到达。何涛决定所有人都下马&#xff0c;一起乘船前往湖中寻找阮家兄弟。 在行船…

C++中的指针空值nullptr

一、nullptr的引入 在C98中&#xff0c;通常是用NULL或者0对指针变量进行初始化 int* p1 NULL; int* p2 0; NULL其实一个宏&#xff0c;本质是0&#xff0c;在传统C头文件stddef.h中给可以看到如下代码 #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define …