Python面试宝典第26题:最长公共子序列

news2024/9/20 22:30:32

题目

        一个字符串的子序列是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。比如:"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。两个字符串的公共子序列是这两个字符串所共同拥有的子序列。

        现给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列 ,返回0。

          备注:text1 和 text2 仅由小写英文字符组成。

          示例 1:

输入:text1 = "abcde", text2 = "ace" 
输出:3  
解释:最长公共子序列是"ace" ,它的长度为3。

        示例 2:

输入:text1 = "abc", text2 = "abc"
输出:3
解释:最长公共子序列是"abc",它的长度为3。

        示例 3:

输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回0。

递归法

        最长公共子序列,英文全称为Longest Common Subsequence,一般缩写为LCS。

        递归法求解LCS的基本思想是:将大问题分解为小问题,通过比较两个字符串的末尾字符是否相等,来决定如何递归地解决问题。如果两个字符串的末尾字符相等,那么这个字符必定属于LCS的一部分。如果不相等,就需要分别去掉一个字符串的末尾字符,递归地求解子问题。使用递归法求解本题的主要步骤如下。

        1、如果任意一个字符串为空,那么最长公共子序列的长度为0。

        2、如果 text1 的最后一个字符和 text2 的最后一个字符相同,那么我们递归地求解 text1[:-1] 和 text2[:-1] 的LCS长度,并在结果上加1。

        3、如果 text1 的最后一个字符和 text2 的最后一个字符不同,那么我们递归地求解 text1[:-1] 和 text2 的LCS长度,以及 text1 和 text2[:-1] 的LCS长度,取两者中较大的一个。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def lcs_by_recursion(text1, text2):
    def lcs_helper(t1, t2):
        if not t1 or not t2:
            return 0
        
        if t1[-1] == t2[-1]:
            # 末尾字符相同
            return lcs_helper(t1[:-1], t2[:-1]) + 1
        else: 
            # 末尾字符不同
            return max(lcs_helper(t1[:-1], t2), lcs_helper(t1, t2[:-1]))

    return lcs_helper(text1, text2)

print(lcs_by_recursion("abcde", "ace"))
print(lcs_by_recursion("abc", "abc"))
print(lcs_by_recursion("abc", "def"))

动态规划法

        动态规划法通过构建一个二维数组来存储子问题的解,以避免重复计算。对于任意两个字符串的前缀,其最长公共子序列的长度取决于前一个字符是否相等:如果相等,则长度加1;如果不等,则取两者可能的最长公共子序列的最大值。使用动态规划法求解本题的主要步骤如下。

        1、初始化。定义一个二维数组 dp,大小为 (len(text1) + 1) x (len(text2) + 1)。初始状态下,dp[0][j] = 0,dp[i][0] = 0。这是因为,空字符串与任何字符串的最长公共子序列长度都为0。

        2、状态转移方程。遍历 text1 和 text2 的每个字符,对于 text1 中的第 i 个字符和 text2 中的第 j 个字符,进行以下操作。

        (1)如果 text1[i-1] 等于 text2[j-1],则 dp[i][j] = dp[i-1][j-1] + 1。

        (2)如果 text1[i-1] 不等于 text2[j-1],则 dp[i][j] = max(dp[i-1][j], dp[i][j-1])。

        3、边界条件。当任一字符串为空时,最长公共子序列长度为0,这已经在初始化时处理。

        4、获取结果。最终答案位于dp数组的右下角,即:dp[len(text1)][len(text2)]。

def lcs_by_dp(text1: str, text2: str) -> int:
    m, n = len(text1), len(text2)
    # 初始化DP表
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    
    # 填充DP表
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if text1[i - 1] == text2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
    
    return dp[m][n]

print(lcs_by_dp("abcde", "ace"))
print(lcs_by_dp("abc", "abc"))
print(lcs_by_dp("abc", "def"))

总结

        虽然递归法直观且易于理解,但它存在严重的重复计算问题,导致时间复杂度为指数级,效率极低。因此,在实际应用中,递归法通常被动态规划法所替代。动态规划法可以避免重复计算,将时间复杂度降低至O(m*n),其中m和n分别是两个字符串的长度。

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

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

相关文章

基于redis实现优惠劵秒杀下单功能(结合黑马视频总结)

基础业务逻辑 初步实现 Override public Result seckillVoucher(Long voucherId) {// 1.查询优惠券SeckillVoucher voucher seckillVoucherService.getById(voucherId);// 2.判断秒杀是否开始if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {// 尚未开始return R…

YOLOv8改进 | 注意力机制 | 反向残差注意力机制【内含创新技巧思维】

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv8改进有效…

【Docker系列】Docker 镜像管理:删除无标签镜像的技巧

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【Webpack 踩坑】CSS加载缓慢

问题:使用webpack5,单独index.scss在assets/css目录下,但是不管是production还是development环境下,都会出现dom加载完后再渲染样式 本意是想要将样式单独打包到一个文件夹,还有压缩css 于是用了mini-css-extract-plug…

【LeetCode】219.存在重复元素II

1. 题目 2. 分析 3. 代码 class Solution:def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:num2index defaultdict(list)for idx,num in enumerate(nums):num2index[num].append(idx)for key, val in num2index.items():if len(val) > 2:for i i…

书生大模型实战营--L1关卡-XTuner 微调个人小助手认知

一、为什么要做模型微调,有些场景下大模型无法更好的回答用户问题 二、准备模型以及训练语料 准备工作详细参考,这里有很详细的介绍 https://github.com/InternLM/Tutorial/blob/camp3/docs/L1/XTuner/readme.md 三、微调模型后的回答,符合…

python 爬虫入门实战——爬取维基百科“百科全书”词条页面内链

1. 简述 本次爬取维基百科“百科全书”词条页面内链,仅发送一次请求,获取一个 html 页面,同时不包含应对反爬虫的知识,仅包含最基础的网页爬取、数据清洗、存储为 csv 文件。 爬取网址 url 为 “https://zh.wikipedia.org/wiki/…

历届奥运会奖牌数据(1896年-2024年7月)

奥运会,全称奥林匹克运动会(Olympic Games),是国际奥林匹克委员会主办的世界规模最大的综合性体育赛事,每四年一届,会期不超过16天。这项历史悠久的赛事起源于古希腊,现代奥运会则始于1896年的希…

opencascade AIS_ViewCube源码学习小方块

opencascade AIS_ViewCube 小方块 前言 用于显示视图操控立方体的交互对象。 视图立方体由多个部分组成,负责不同的相机操作: 立方体的各个面代表主视图:顶部、底部、左侧、右侧、前侧和后侧。 边表示主视图之一的旋转45度。 顶点表示主视…

3143. 正方形中的最多点数 Medium

给你一个二维数组 points 和一个字符串 s ,其中 points[i] 表示第 i 个点的坐标,s[i] 表示第 i 个点的 标签 。 如果一个正方形的中心在 (0, 0) ,所有边都平行于坐标轴,且正方形内 不 存在标签相同的两个点,那么我们称…

ChatGPT协助撰写研究论文的11种方法【全集】

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 当我们使用 ChatGPT 时,原本那些需要花费数小时、数天、有时甚至更长时间的任务现在只需几分钟甚至更短时间。 今天的分享,我们将谈谈 ChatGPT 在研究论文方面可…

右键空白处自定义菜单

效果 建立二级菜单 winr输入 regedit 路径复制到地址栏,回车即可定位。 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\如果没有地址栏 在shell上右键,新建项,名字随意但最好是英文(…

免费开源!PDF加盖骑缝章小工具PDFQFZ

PDFQFZ是一款免费开源的PDF加盖骑缝章小工具,主要用于给多页合同等PDF文件添加骑缝章,以达到防伪效果。该工具支持对PDF文件或文件夹进行随机分割、印章设定、骑缝章等操作,生成加盖骑缝章的PDF文件。 主要功能: 支持加密PDF文件…

Python安装教程(Window环境)

1 Python安装 1.1 Python官网下载 1)在Python官网选择Python版本(这里选择Python 3.12.4),点击对应的【Download】按钮下载。2)根电脑的操作系统类型选择(这里电脑64位操作系统),点…

【商品支付】漏洞详解!

产生原因: 订单金额的验证:价格未保存在数据库中未校验商品价格与数据库中是否匹配 不安全的传输: 订单相关信息未进行加密传输(话说你加密的地方一定是重要地方,你不加密,你就是有病,哈哈哈) 验证规…

(超全)Kubernetes 的核心组件解析

引言 在现代软件开发和运维的世界中,容器化技术已经成为一种标志性的解决方案,它为应用的构建、部署和管理提供了前所未有的灵活性和效率。然而,随着应用规模的扩大和复杂性的增加,单纯依靠容器本身来管理这些应用和服务已不再足够…

gitlab 服务器安装

阿里云盘快传 百度链接 链接:https://pan.baidu.com/s/1Gn5bWHi45Dcpe1RH1S06dw 提取码:yai2 然后就是有一台服务器 cd /mkdir gitlab上传下载好的东西rpm -ivh gitlab-ce-10.8.4-ce.0.el7.x86_64.rpm 这里可以tab提示vim /etc/gitlab/gitlab.rb我建议…

【JavaEE精炼宝库】 网络编程套接字——UDP业务逻辑 | TCP流套接字编程及业务逻辑实现

文章目录 一、UDP业务逻辑实现二、TCP流套接字编程2.1 API 介绍:2.1.1 ServerSocket:2.1.2 Socket: 2.2 Java流套接字通信模型:2.3 代码示例:2.3.1 TCP Echo Server:2.3.2 TCP Echo Client:2.3.…

【刷题汇总 -- 爱吃素、相差不超过k的最多数、最长公共子序列(一)】

C日常刷题积累 今日刷题汇总 - day0261、爱吃素1.1、题目1.2、思路1.3、程序实现 2、相差不超过k的最多数2.1、题目2.2、思路2.3、程序实现 -- 滑动窗口 3、最长公共子序列(一)3.1、题目3.2、思路3.3、程序实现 -- dp 4、题目链接 今日刷题汇总 - day026 1、爱吃素 1.1、题目…

自写Json转换工具

前面写了简单的API测试工具ApiTools,返回的json有时需要做很多转换,于是开发了这个工具。 功能包括 1、json字符串转为表格,可以直观的展示,也可以复制,并支持转换后的表格点击列头进行排序,比较方便地定…