牛客NC196 编辑距离(一)【较难 DFS/DP,动态规划,样本对应模型 Java,Go,PHP】

题目

在这里插入图片描述
题目链接:
https://www.nowcoder.com/practice/6a1483b5be1547b1acd7940f867be0da

思路

编辑距离问题
什么是两个字符串的编辑距离(edit distance)?给定字符串s1和s2,以及在s1上的如下操作:

插入(Insert)一个字符
移除(Remove)一个字符
替换(Replace)一个字符
试问最小需要多少次这样的操作才能使得s1转换为s2?
比如,单词“cat”和“hat”,这样的操作最少需要一次,只需要把“cat”中的“c”替换为“h”即可。
单词“recall”和“call”,这样的操作最少需要两次,只需要把“recall”中的“r”和“e”去掉即可。
单词“Sunday”和“Saturday”,这样的操作最少需要3次,在“Sunday”的“S”和“u”中插入“a”和“t”,
再把“n”替换成“r”即可。

那么,是否存在一种高效的算法,能够快速、准确地计算出两个字符串的编辑距离呢?

动态规划算法
  我们使用动态规划算法(Dynamic Programming)来计算出两个字符串的编辑距离。
  我们从两个字符串s1和s2的最末端向前遍历来考虑。假设s1的长度为m,s2的长度为n,算法如下:

 如果两个字符串的最后一个字符一样,那么,我们就可以递归地计算长度为m-1和n-1的两个字符串的情形;
如果两个字符串的最后一个字符不一样,那么,进入以下三种情形:
插入: 递归地计算长度为m和n-1的两个字符串的情形,
这是因为在s1中的末端插入了一个s2的最后一个字符,这样s1和s2的末端字符一样,就是1中情形;
删除: 递归地计算长度为m-1和n的两个字符串的情形,这是在s1中的末端删除了一个字符;
替换: 递归地计算长度为m-1和n-1的两个字符串的情形,
这是因为把s1中末端字符替换成了s2的最后一个字符,这样s1和s2的末端字符一样,就是1中情形;

这样,我们就有了子结构问题。对于动态规划算法,我们还需要一个初始化的过程,
然后中间维护一张二维表即可。初始化的过程如下: 如果m为0,则至少需要操作n次,
即在s1中逐个添加s2的字符,一共是n次;如果n为0,则至少需要操作m次,
即把s1的字符逐个删除即可,一共是m次。

参考文档:https://www.cnblogs.com/jclian91/p/10184039.html
本答案采用递归实现,注意必须用缓存,否则时间复杂度过大

参考答案Java

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param str1 string字符串
     * @param str2 string字符串
     * @return int整型
     */
    public int editDistance (String str1, String str2) {
        //动态规划:样本对应模型
        int n = str1.length();
        int m = str2.length();
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                dp[i][j] = -1;
            }
        }

        return dfs(str1, str2, n, m, 1, dp);
    }

    public int dfs(String str1, String str2, int i, int j, int c, int[][] dp) {
        if (dp[i][j] != -1)
            return dp[i][j];

        int ans = 0;
        if (i == 0 && j == 0) ans = 0;
        else if (i == 0) ans = c * j;
        else if (j == 0) ans = c * i;
        else {
            ans = dfs(str1, str2, i - 1, j - 1, c,
                      dp) + ((str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0 : c);
            int ans1 = dfs(str1, str2, i, j - 1, c, dp) + c;
            if (ans > ans1) ans = ans1;
            int ans2 = dfs(str1, str2, i - 1, j, c, dp) + c;
            if (ans > ans2)
                ans = ans2;
        }
        dp[i][j] = ans;
        return ans;
    }
}

参考答案Go

package main


/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param str1 string字符串 
 * @param str2 string字符串 
 * @return int整型
*/
func editDistance( str1 string ,  str2 string ) int {
    //动态规划:样本对应模型
	n := len(str1)
	m := len(str2)

	dp := make([][]int, n+1)
	for i := 0; i <= n; i++ {
		dp[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			dp[i][j] = -1
		}
	}

	return dfs(str1, str2, n, m, 1, dp)
}

func dfs(s1 string, s2 string, i int, j int, cnt int, dp [][]int) int {
	if dp[i][j] != -1 {
		return dp[i][j]
	}

	var ans int = 0
	if i == 0 && j == 0 {
		ans = 0
	} else if i == 0 {
		ans = j * cnt
	} else if j == 0 {
		ans = i * cnt
	} else {
		cur := cnt
		if s1[i-1] == s2[j-1] {
			cur = 0
		}
		ans = dfs(s1, s2, i-1, j-1, cnt, dp) + cur
		ans1 := dfs(s1, s2, i, j-1, cnt, dp) + cnt
		if ans > ans1 {
			ans = ans1
		}
		
		ans2 := dfs(s1, s2, i-1, j, cnt, dp) + cnt
		if ans > ans2 {
			ans = ans2
		}
	}
	dp[i][j] = ans

	return ans
}

参考答案PHP

<?php


/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param str1 string字符串 
 * @param str2 string字符串 
 * @return int整型
 */
function editDistance( $str1 ,  $str2 )
{
   //动态规划:样本对应模型
    $n = strlen($str1);
    $m = strlen($str2);
    $dp = [];

    for ($i = 0; $i <= $n; $i++) {
        for ($j = 0; $j <= $m; $j++) {
            $dp[$i][$j] = -1;
        }
    }

    return dfs($str1, $str2, $n, $m, 1, $dp);
}

function dfs($s1, $s2, $i, $j, $cnt, &$dp)
{
    if ($dp[$i][$j] != -1) {
        return $dp[$i][$j];
    }

    $ans = 0;
    if ($i == 0 && $j == 0) $ans = 0;
    else if ($i == 0) $ans = $j * $cnt;
    else if ($j == 0) $ans = $i * $cnt;
    else {
        $cur = $s1[$i - 1] == $s2[$j - 1] ? 0 : $cnt;
        $ans = dfs($s1, $s2, $i - 1, $j - 1, $cnt, $dp) + $cur;

        $ans1 = dfs($s1, $s2, $i, $j - 1, $cnt, $dp)+$cnt;
        if ($ans > $ans1) $ans = $ans1;

        $ans2 = dfs($s1, $s2, $i - 1, $j, $cnt, $dp)+$cnt;
        if ($ans > $ans2)
            $ans = $ans2;

    }
    $dp[$i][$j] = $ans;
    return $ans;

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ARM】DSTREAM上面的各个指示灯代表什么意思?

【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 对于DStream仿真器上面的指示灯亮灭代表的意义进行分析。 2、 问题场景 主要对于DStream仿真器的使用过程中&#xff0c;不同的情况下面仿真器的指示灯会进行相应的亮灭。了解一下不同指示灯的亮灭所提示的信息…

部署Prometheus+grafana详解

目录 一、prometheus 介绍 二、prometheus 对比 zabbix 三、prometheus 监控插件 四、部署 1、下载所需的包 2.编辑prometheus的配置文件 3、编辑alertmanager 的配置文件 4、tmpl 模板&#xff08;将此文件创建在/opt/alertmanager/tmpl/&#xff09; 5.启动&#xff0…

Google colab中如何从kaggle中接入数据?

写在前面 使用google colab进行数据分析和探索时&#xff0c;可引用的数据源包括但不限于&#xff1a;1.可上传的数据文件用本地加载的的方式打开数据资源&#xff1b;2.从网络链接中直接打开后加载到缓存中的文件资源&#xff1b;3.通过API或者外部的开放接口加载数据&#x…

人生亏钱指南pdf分享【谨防上当】【警钟长鸣】不知道动了多少人蛋糕,看到后赶快收藏起来

查理芒格&#xff1a;如果知道我会死在哪里&#xff0c;那我将永远不去那个地方 书中分别投资篇、知识付费篇、合伙合作篇、实体项目篇、欺诈篇、借贷篇、健康篇等方向详细解释可能亏钱的坑&#xff01; 书中说到&#xff1a; 成年人的世界&#xff0c;踩坑已是日常&#xff0…

java框架 2 springboot 过滤器 拦截器 异常处理 事务管理 AOP

Filter 过滤器 对所有请求都可以过滤。 实现Filter接口&#xff0c;重写几个方法&#xff0c;加上WebFilter注解&#xff0c;表示拦截哪些路由&#xff0c;如上是所有请求都会拦截。 然后还需要在入口处加上SvlterComponentScan注解&#xff0c;因为Filter是javaweb三大组件之…

计算机二级C语言的注意事项及相应真题-6-程序设计

目录 51.将a所指数组主对角线上的元素分别乘以2;次对角线上的元素分别乘以3&#xff0c;依次放入指针p所指的数组中。计算过程中不得修改a所指数组中的数据52.将a、b中的两个两位正整数合并形成一个新的整数放在c中。合并的方式是:将a中的十位和个位数依次放在变量c的十位和千位…

面试算法-62-盛最多水的容器

题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。…

Java------数据结构之栈与队列(简单讲解)

本篇碎碎念&#xff1a;时隔n个月&#xff0c;继续写博客&#xff0c;假期落下的进度&#xff0c;在开学后努力追赶&#xff0c;假期不努力&#xff0c;开学徒伤悲啊&#xff0c;此时此刻真想对自己说一句&#xff0c;活该啊~~~~ 欠下的链表练习题讲解会在下次更新~~~~ 今日份励…

基于Springboot的在线投稿系统+数据库+免费远程调试

项目介绍: Javaee项目&#xff0c;springboot项目。采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring SpringBoot Mybatis VueMavenLayui来实现。MySQL数据库作为系统数据储存平台&a…

第十二届蓝桥杯省赛CC++ 研究生组-砝码称重

solution1&#xff08;通过10%&#xff09; 写了几种可能的组合方式&#xff0c;骗到一丢丢分数 #include<iostream> #include<algorithm> #include<map> using namespace std; int main(){int n, a[110], count 0, sum[110] {0};map<int, int> mp…

Windows系统部署GoLand结合内网穿透实现SSH远程Linux服务器开发调试

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-HIOuHATnug3qMHzx {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

PTA L2-041 插松枝 代码附注释

人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。每人面前有用不完的松枝干和一个推送器&#xff0c;每次推送一…

本地项目文件夹创建python文件并配置conda环境的完整流程

1 在Pycharm中创建新项目 位置就是本地的项目文件夹 2 接着打开pycharm的终端 创建conda环境&#xff08;这个过程需要保证conda.exe能够被系统路径识别&#xff09; conda create --name my_environment&#xff08;my_environment取自己想要的环境名字&#xff09; 还可以指…

(附源码)基于Spring Boot + Vue的校园综合信息服务平台设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2024年Java精品实战案例《100套》 &#x1f345;文末获取源码联系&#x1f345; &#x1f31…

1.2 编译型语言和解释型语言的区别

编译型语言和解释型语言的区别 通过高级语言编写的源码&#xff0c;我们能够轻松理解&#xff0c;但对于计算机来说&#xff0c;它只认识二进制指令&#xff0c;源码就是天书&#xff0c;根本无法识别。源码要想执行&#xff0c;必须先转换成二进制指令。 所谓二进制指令&…

2024年上半年PETS5考试提醒/北语考前培训班(线上)招

PEST5考试每年进行两次&#xff0c;上半年和下半年各一次。目前尚未公布2024年的报考计划&#xff0c;但可以参考2023年度信息&#xff0c;上半年报名时间&#xff1a;4月11日-4月13日&#xff1b;考试时间&#xff1a;5月20日-5月21日。知识人网小编提醒拟申报者关注报考日期&…

聚焦两会:数字化再加速,VR全景助力制造业转型

近年来&#xff0c;随着信息技术、人工智能、VR虚拟现实等新兴技术的不断涌现&#xff0c;数字化正日益成为推动当今经济发展的新驱动力。在不久前的两会上&#xff0c;数字化经济和创新技术再度成为热门话题&#xff1a; 国务院总理李强作政府工作报告&#xff1a; 要深入推…

2024.3.21 QT

思维导图 自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面。&#xff08;不要使用课堂上的图片和代码&#xff0c;自己发挥&#xff0c;有利于后面项目的完成&#xff09; 要求&#xff1a; 1. 需要使用Ui界面文件进行界面设计 2. ui界面上的组件相关设置&…

如何设计一个安全的API接口详解

前言 在日常开发中&#xff0c;总会接触到各种接口。前后端数据传输接口&#xff0c;第三方业务平台接口。一个平台的前后端数据传输接口一般都会在内网环境下通信&#xff0c;而且会使用安全框架&#xff0c;所以安全性可以得到很好的保护。这篇文章重点讨论一下提供给第三方…

【ai技术】(3):树莓派4,成功安装ollama软件,内存4G,推荐使用命令行界面安装,使用raspi-config配置wifi,运行速度飞快

1&#xff0c;关于raspberrypi 4 项目 https://www.bilibili.com/video/BV1K2421P71h/ 【ai技术】&#xff08;3&#xff09;&#xff1a;树莓派4&#xff0c;成功安装ollama软件&#xff0c;内存4G&#xff0c;安装命令行版本&#xff0c;使用raspi-config配置wifi&#xff0…