牛客NC92 最长公共子序列(二)【中等 动态规划 Java,Go,PHP】

news2024/12/23 22:50:00

题目

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

思路

https://blog.csdn.net/qq_36544411/article/details/120021203
思路
动态规划法,
我们以dp[i][j]表示在s1中以第i个元素结尾,s2中以第j个元素结尾的字符串的最长公共子序列长度,
若是i与j相等,则该问题可以变成1+dp[i−1][j−1],即最长公共子序列长度加1,若是不相等,
则换成两个子问题:dp[i][j−1]或者dp[i−1][j],由此用递归或者动态规划即可以解决。

求出递归公式,为
 if s1.charAt(i-1) == s2.charAt(j-1)  dp[i][j]=dp[i-1][j-1]+1
 else  dp[i][j]= Math.max(dp[i-1][j],dp[i][j-1])

反推求出子序列。只需要求其中一个。

参考答案Java

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * longest common subsequence
     * @param s1 string字符串 the string
     * @param s2 string字符串 the string
     * @return string字符串
     */
    public String LCS (String s1, String s2) {
        /*
           https://blog.csdn.net/qq_36544411/article/details/120021203
           思路
           动态规划法,
           我们以dp[i][j]表示在s1中以第i个元素结尾,s2中以第j个元素结尾的字符串的最长公共子序列长度,
           若是i与j相等,则该问题可以变成1+dp[i−1][j−1],即最长公共子序列长度加1,若是不相等,
           则换成两个子问题:dp[i][j−1]或者dp[i−1][j],由此用递归或者动态规划即可以解决。

           求出递归公式,为
           if s1.charAt(i-1) == s2.charAt(j-1)  dp[i][j]=dp[i-1][j-1]+1
           else  dp[i][j]= Math.max(dp[i-1][j],dp[i][j-1])

           反推求出子序列。只需要求其中一个。

            */
        int n = s1.length();
        int m = s2.length();
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 0; i <= n ; i++) {
            for (int j = 0; j <= m ; j++) {
                if (i == 0 || j == 0) {
                    dp[i][j] = 0;
                } else {

                    if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                    } else {
                        dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                    }
                }
            }
        }

        Stack<Character> stack = new Stack<>();
        while (n > 0 && m > 0) {
            if (s1.charAt(n - 1) == s2.charAt(m - 1)) {
                stack.add(s1.charAt(n - 1));
                n--;
                m--;
            } else if (dp[n - 1][m] >= dp[n][m - 1]) {
                n--;
            } else {
                m--;
            }
        }

        StringBuilder sb = new StringBuilder();
        while (!stack.isEmpty()) {
            sb.append(stack.pop());
        }

        return sb.length() == 0 ? "-1" : sb.toString();
    }
}

参考答案Go

package main

import "fmt"

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * longest common subsequence
 * @param s1 string字符串 the string
 * @param s2 string字符串 the string
 * @return string字符串
 */
func LCS(s1 string, s2 string) string {
	/*
	   https://blog.csdn.net/qq_36544411/article/details/120021203
	   思路
	   动态规划法,
	   我们以dp[i][j]表示在s1中以第i个元素结尾,s2中以第j个元素结尾的字符串的最长公共子序列长度,
	   若是i与j相等,则该问题可以变成1+dp[i−1][j−1],即最长公共子序列长度加1,若是不相等,
	   则换成两个子问题:dp[i][j−1]或者dp[i−1][j],由此用递归或者动态规划即可以解决。

	   求出递归公式,为
	   if s1.charAt(i-1) == s2.charAt(j-1)  dp[i][j]=dp[i-1][j-1]+1
	   else  dp[i][j]= Math.max(dp[i-1][j],dp[i][j-1])

	   反推求出子序列。只需要求其中一个。
	*/

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

	for i := 0; i <= n; i++ {
		for j := 0; j <= m; j++ {
			if i == 0 || j == 0 {
				dp[i][j] = 0
			} else {
				if s1[i-1] == s2[j-1] {
					dp[i][j] = dp[i-1][j-1] + 1
				} else {
					cur1 := dp[i-1][j]
					cur2 := dp[i][j-1]
					if cur1 > cur2 {
						dp[i][j] = cur1
					} else {
						dp[i][j] = cur2
					}
				}
			}
		}
	}

	stack := []byte{}
	for n > 0 && m > 0 {
		if s1[n-1] == s2[m-1] {
			stack = append(stack, s1[n-1])
			n--
			m--
		} else if dp[n-1][m] >= dp[n][m-1] {
			n--
		} else {
			m--
		}
	}

	s3 := ""
	for k := len(stack) - 1; k >= 0; k-- {
		s3 = fmt.Sprintf("%s%s", s3, string(stack[k]))
	}

	if len(s3) == 0 {
		return "-1"
	} else {
		return s3
	}
}

参考答案PHP

<?php


/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * longest common subsequence
 * @param s1 string字符串 the string
 * @param s2 string字符串 the string
 * @return string字符串
 */
function LCS( $s1 ,  $s2 )
{
     /*
	   https://blog.csdn.net/qq_36544411/article/details/120021203
	   思路
	   动态规划法,
	   我们以dp[i][j]表示在s1中以第i个元素结尾,s2中以第j个元素结尾的字符串的最长公共子序列长度,
	   若是i与j相等,则该问题可以变成1+dp[i−1][j−1],即最长公共子序列长度加1,若是不相等,
	   则换成两个子问题:dp[i][j−1]或者dp[i−1][j],由此用递归或者动态规划即可以解决。

	   求出递归公式,为
	   if s1.charAt(i-1) == s2.charAt(j-1)  dp[i][j]=dp[i-1][j-1]+1
	   else  dp[i][j]= Math.max(dp[i-1][j],dp[i][j-1])

	   反推求出子序列。只需要求其中一个。
	*/

    $n=strlen($s1);
    $m= strlen($s2);
    $dp=array();
    for($i=0;$i<=$n;$i++){
        for($j=0;$j<=$m;$j++){
            if($i==0 || $j==0){
                $dp[$i][$j]=0;
            }else{
                if($s1[$i-1] == $s2[$j-1]){
                    $dp[$i][$j]=$dp[$i-1][$j-1]+1;
                }else{
                    $cur1= $dp[$i-1][$j];
                    $cur2 = $dp[$i][$j-1];

                    if($cur1>$cur2){
                        $dp[$i][$j] = $cur1;
                    }else{
                        $dp[$i][$j] = $cur2;
                    }
                }
            }
        }
    }

    $stack = array();
    $idx=0;
    while ($n>0 && $m>0){
        if($s1[$n-1] == $s2[$m-1]){
            $stack[$idx++] = $s1[$n-1];
            $n--;
            $m--;
        }else if($dp[$n-1][$m]>= $dp[$n][$m-1]){
            $n--;
        }else{
            $m--;
        }
    }

    if($idx==0) return "-1";
    $s3="";
    for(--$idx;$idx>=0;$idx--){
        $s3.=$stack[$idx];
    }

    return $s3;
}

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

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

相关文章

【JavaSE】初识线程,线程与进程的区别

文章目录 ✍线程是什么&#xff1f;✍线程和进程的区别✍线程的创建1.继承 Thread 类2.实现Runnable接口3.匿名内部类4.匿名内部类创建 Runnable ⼦类对象5.lambda 表达式创建 Runnable ⼦类对象 ✍线程是什么&#xff1f; ⼀个线程就是⼀个 “执行流”. 每个线程之间都可以按…

常见微服务的组件?

注册中心&#xff1a;就是一个服务注册的地方&#xff0c;我们可以把拆分的服务注册到注册中心&#xff0c;这样注册中心就能管理这些服务&#xff0c;服务之间的调用就会很方便&#xff0c;通过服务名就能相互调用。 负载均衡&#xff1a;被调用放的负载均衡&#xff0c;比如…

人工智能产业应用--具身智能

五、下一个浪潮 (一) 跳出缸中脑——虚实结合 在探索人工智能的边界时&#xff0c;“跳出缸中脑——虚实结合”这一概念提出了一个引人深思的视角&#xff0c;尤其是在具身智能的领域。具身智能是一种思想&#xff0c;强调智能体通过与其环境的直接物理互动来实现智能行为。然…

[MSSQL]理解SQL Server AlwaysOn AG的备份

AG提供了以下几种备份策略 下面来看看各项的解释 Prefer Secondary(首选辅助副本) 应在辅助副本上执行此可用性组的自动备份。如果没有可用的辅助副本,将在主副本上执行备份。 这个选项只是概念上的选项。基本上,用户可以从任何复制节点上执行备份命令。 我们可以在主副本…

Django DRF视图

文章目录 一、DRF类视图介绍APIViewGenericAPIView类ViewSet类ModelViewSet类重写方法 二、Request与ResponseRequestResponse 参考 一、DRF类视图介绍 在DRF框架中提供了众多的通用视图基类与扩展类&#xff0c;以简化视图的编写。 • View&#xff1a;Django默认的视图基类&…

数据结构堆

前言&#xff1a; 在前面我们已经学习了数据结构的基础操作&#xff1a;顺序表和链表及其相关内容&#xff0c;今天我们来学一点有些难度的知识——数据结构中的二叉树&#xff0c;今天我们先来学习二叉树中堆的知识&#xff0c;这部分内容还是非常有意思的&#xff0c;下面我们…

设计模式学习笔记 - 设计模式与范式 -行为型:2.观察者模式(下):实现一个异步非阻塞的EventBus框架

概述 《1.观察者模式&#xff08;上&#xff09;》我们学习了观察者模式的原理、实现、应用场景&#xff0c;重点节介绍了不同应用场景下&#xff0c;几种不同的实现方式&#xff0c;包括&#xff1a;同步阻塞、异步非阻塞、进程内、进程间的实现方式。 同步阻塞最经典的实现…

【 书生·浦语大模型实战营】学习笔记(一):全链路开源体系介绍

&#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料&#xff0c;配有全面而有深度的专栏内容&#xff0c;包括不限于 前沿论文解读、…

【Linux】TCP网络套接字编程+守护进程

文章目录 日志类&#xff08;完成TCP/UDP套接字常见连接过程中的日志打印&#xff09;单进程版本的服务器客户端通信多进程版本和多线程版本守护进程化的多线程服务器 日志类&#xff08;完成TCP/UDP套接字常见连接过程中的日志打印&#xff09; 为了让我们的代码更规范化&…

鸿蒙实战开发-如何使用声明式UI编程框架的基础组件

介绍 在本教程中&#xff0c;我们将通过一个简单的样例&#xff0c;学习如何使用声明式UI编程框架的基础组件。本篇Codelab将会使用Image组件、Slider组件、Text组件共同实现一个可调节的风车动画&#xff0c;实现效果如图所示 相关概念 Text组件&#xff1a;文本组件&#x…

9.Python类与对象

1 面向对象 类和对象都是面向对象中的重要概念。面向对象是一种编程思想&#xff0c; 即按照真实世界的思维方式构建软件系统。 例如&#xff0c;在真实世界的校园里有学生和老师&#xff0c;学生有学号、姓名、所 在班级等属性&#xff08;数据&#xff09;&#xff0c;还有…

MAC的Safari浏览器没有声音解决办法

有一段时间没打开电脑&#xff0c;也不知道是系统自动更新或是什么缘故&#xff0c;所有浏览器都无法正常发声。 现象如下&#xff1a; 首先&#xff0c;Safari浏览器无法自动播放声音&#xff0c;下载的360浏览器现象一致&#xff0c;但是播放其他音乐播放软件和视频软件都正…

Java 面试宝典:请说下你对 Netty 中Reactor 模式的理解

大家好&#xff0c;我是大明哥&#xff0c;一个专注「死磕 Java」系列创作的硬核程序员。 本文已收录到我的技术网站&#xff1a;https://skjava.com。有全网最优质的系列文章、Java 全栈技术文档以及大厂完整面经 回答 Reactor 模式是一种高效处理并发网络事件的设计模式&…

新手使用GIT上传本地项目到Github(个人笔记)

亲测下面的文章很有用处。 1. 初次使用git上传代码到github远程仓库 - 知乎 (zhihu.com) 2. 使用Git时出现refusing to merge unrelated histories的解决办法 - 知乎

五、Yocto集成QT5(基于Raspberrypi 4B)

Yocto集成QT5 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第五篇文章&#xff1a; 一、yocto 编译raspberrypi 4B并启动 二、yocto 集成ros2(基于raspberrypi 4B) 三、Yocto创建自定义的layer和image 四、Yocto创建静态IP和VLAN 本章节实操代码请查看github仓库&…

yolov5 v7.0打包exe文件,使用C++调用

cd到yolo5文件夹下 pyinstaller -p 当前路径 -i logo图标 detect.py问题汇总 运行detect.exe找不到default.yaml 这个是yolov8里的文件 1 复制权重文件到exe所在目录。 2 根据报错提示的配置文件路径&#xff0c;把default.yaml复制放到相应的路径下。&#xff08;缺少相应…

Linux的开发工具(二):编译器gcc/g++与Linux项目自动化构建工具-Makefile

Linux的编译器-gcc/g 基本概念&#xff1a;gcc是专门用来编译c语言的&#xff0c;g可以编译c或c语言 问题一&#xff1a;gcc有时候为什么不能编译带有for循环的c语言源文件&#xff1f; 答&#xff1a;gcc版本过低会不支持for循环等c99标准下的内容 解决方式&#xff1a;gcc…

Spring定义Bean对象笔记

前言&#xff1a;面向对象语言最基本的元素就是对象&#xff0c;在Spring中把对象都封装为一个个的Bean&#xff0c;即通过Bean容器来管理对象&#xff1b;那么接下来我们看下在Spring中如何创建所需要的Bean。 一、环境准备 员工类 package com.xlb.bean;public class Empl…

在 C#和ASP.NET Core中创建 gRPC 客户端和服务器

关于gRPC和Google protobuf gRPC 是一种可以跨语言运行的现代高性能远程过程调用 (RPC) 框架。gRPC 实际上已经成为 RPC 框架的行业标准&#xff0c;Google 内外的组织都在使用它来从微服务到计算的“最后一英里”&#xff08;移动、网络和物联网&#xff09;的强大用例。 gRP…

数据结构——二叉树——堆

前言&#xff1a; 在前面我们已经学习了数据结构的基础操作&#xff1a;顺序表和链表及其相关内容&#xff0c;今天我们来学一点有些难度的知识——数据结构中的二叉树&#xff0c;今天我们先来学习二叉树中堆的知识&#xff0c;这部分内容还是非常有意思的&#xff0c;下面我们…