代码随想录算法训练营第四十七天|1143.最长公共子序列、 1035.不相交的线、53. 最大子序和、392.判断子序列

1143.最长公共子序列

在这里插入图片描述

题目链接:1143.最长公共子序列
文档讲解:代码随想录
状态:一开始没想明白为啥要 max(dp[i - 1][j], dp[i][j - 1])

思路:
如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;

如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。

即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

题解:

    // 二维动态规划方法
    public int longestCommonSubsequence(String text1, String text2) {
        char[] chars1 = text1.toCharArray();
        char[] chars2 = text2.toCharArray();
        int m = chars1.length;
        int n = chars2.length;

        // 创建二维dp数组,dp[i][j]表示text1前i个字符和text2前j个字符的最长公共子序列长度
        int[][] dp = new int[m + 1][n + 1];

        // 遍历每个字符,填充dp数组
        for (int i = 1; i <= chars1.length; i++) {
            for (int j = 1; j <= chars2.length; j++) {
                if (chars1[i - 1] == chars2[j - 1]) {
                    // 如果字符相等,则当前状态等于左上角状态加1
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    // 如果字符不相等,则当前状态等于上方和左方状态的最大值
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }

        // 返回最终结果,dp[m][n]即为最长公共子序列长度
        return dp[m][n];
    }

    // 一维动态规划方法(空间优化)
    public int longestCommonSubsequence2(String text1, String text2) {
        char[] chars1 = text1.toCharArray();
        char[] chars2 = text2.toCharArray();
        int n = chars2.length;

        // 创建一维dp数组,dp[j]表示text1前i个字符和text2前j个字符的最长公共子序列长度
        int[] dp = new int[n + 1];

        // 遍历每个字符,填充dp数组
        for (int i = 1; i <= chars1.length; i++) {
            int pre = dp[0]; // 保存左上角的值
            for (int j = 1; j <= chars2.length; j++) {
                int cur = dp[j]; // 当前dp[j]的值,在更新dp[j]之前保存它
                if (chars1[i - 1] == chars2[j - 1]) {
                    // 如果字符相等,则当前状态等于左上角状态加1
                    dp[j] = pre + 1;
                } else {
                    // 如果字符不相等,则当前状态等于上方和左方状态的最大值
                    dp[j] = Math.max(dp[j], dp[j - 1]);
                }
                pre = cur; // 更新pre为当前dp[j]的值
            }
        }

        // 返回最终结果,dp[n]即为最长公共子序列长度
        return dp[n];
    }

1035.不相交的线

在这里插入图片描述

题目链接:1035.不相交的线
文档讲解:代码随想录
状态:还行

思路:
直线不能相交,这就是说明在字符串A中 找到一个与字符串B相同的子序列,且这个子序列不能改变相对顺序,只要相对顺序不改变,链接相同数字的直线就不会相交。
所以,本题说是求绘制的最大连线数,其实就是求两个字符串的最长公共子序列的长度!

题解:

class Solution {
    // 二维动态规划方法
    public int maxUncrossedLines(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        
        // 创建二维dp数组,dp[i][j]表示nums1前i个元素和nums2前j个元素能形成的最大不相交的线数
        int[][] dp = new int[m + 1][n + 1];

        // 遍历每个元素,填充dp数组
        for (int i = 1; i <= nums1.length; i++) {
            for (int j = 1; j <= nums2.length; j++) {
                if (nums1[i - 1] == nums2[j - 1]) {
                    // 如果元素相等,则当前状态等于左上角状态加1
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    // 如果元素不相等,则当前状态等于上方和左方状态的最大值
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }

        // 返回最终结果,dp[m][n]即为最大不相交的线数
        return dp[m][n];
    }

    // 一维动态规划方法(空间优化)
    public int maxUncrossedLines2(int[] nums1, int[] nums2) {
        int n = nums2.length;
        
        // 创建一维dp数组,dp[j]表示nums1前i个元素和nums2前j个元素能形成的最大不相交的线数
        int[] dp = new int[n + 1];

        // 遍历每个元素,填充dp数组
        for (int i = 1; i <= nums1.length; i++) {
            int pre = dp[0]; // 保存左上角的值
            for (int j = 1; j <= nums2.length; j++) {
                int cur = dp[j]; // 当前dp[j]的值,在更新dp[j]之前保存它
                if (nums1[i - 1] == nums2[j - 1]) {
                    // 如果元素相等,则当前状态等于左上角状态加1
                    dp[j] = pre + 1;
                } else {
                    // 如果元素不相等,则当前状态等于上方和左方状态的最大值
                    dp[j] = Math.max(dp[j], dp[j - 1]);
                }
                pre = cur; // 更新pre为当前dp[j]的值
            }
        }

        // 返回最终结果,dp[n]即为最大不相交的线数
        return dp[n];
    }
}

53. 最大子序和

在这里插入图片描述

题目链接:53. 最大子序和
文档讲解:代码随想录
状态:还行

思路:
dp[i]只有两个方向可以推出来:

dp[i - 1] + nums[i],即:nums[i]加入当前连续子序列和
nums[i],即:从头开始计算当前连续子序列和

题解:

   // 贪心算法:每次加上的数字如果不能使sum增加,那就从下个数字开始
    public int maxSubArray(int[] nums) {
        int max = nums[0]; // 初始化最大子数组和为数组的第一个元素
        int sum = 0; // 当前子数组和
        for (int num : nums) {
            sum += num; // 更新当前子数组和
            max = Math.max(max, sum); // 更新最大子数组和
            if (sum <= 0) {
                sum = 0; // 如果当前子数组和为负数或0,从下一个元素重新开始计算
            }
        }
        return max; // 返回最大子数组和
    }

    // 动态规划算法:dp[i]表示以第i个元素结尾的最大子数组和
    public int maxSubArray2(int[] nums) {
        int[] dp = new int[nums.length + 1]; // 创建dp数组,长度为nums.length+1
        dp[0] = nums[0]; // 初始化dp[0]为数组的第一个元素
        int max = nums[0]; // 初始化最大子数组和为数组的第一个元素
        for (int i = 1; i < nums.length; i++) {
            // dp[i]表示以第i个元素结尾的最大子数组和
            dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
            // 更新最大子数组和
            max = Math.max(max, dp[i]);
        }
        return max; // 返回最大子数组和
    }

392.判断子序列

在这里插入图片描述

题目链接:392.判断子序列
文档讲解:代码随想录
状态:so easy

思路:
可以双指针,也可以动态规划。

题解:

    // 双指针方法判断s是否为t的子序列
    public boolean isSubsequence(String s, String t) {
        // 将字符串s和t转换为字符数组
        char[] sChars = s.toCharArray();
        char[] tChars = t.toCharArray();

        // 初始化两个指针,分别指向sChars和tChars的起始位置
        int j = 0;

        // 遍历tChars数组
        for (int i = 0; i < tChars.length && j < sChars.length; i++) {
            // 如果当前字符相等,则移动指向sChars的指针
            if (tChars[i] == sChars[j]) {
                j++;
            }
        }

        // 如果j等于sChars的长度,说明s是t的子序列
        return j == sChars.length;
    }

    public boolean isSubsequence2(String s, String t) {
        char[] chars1 = s.toCharArray();
        char[] chars2 = t.toCharArray();
        int n = chars2.length;

        // 创建一维dp数组,dp[j]表示text1前i个字符和text2前j个字符的最长公共子序列长度
        int[] dp = new int[n + 1];

        // 遍历每个字符,填充dp数组
        for (int i = 1; i <= chars1.length; i++) {
            int pre = dp[0]; // 保存左上角的值
            for (int j = 1; j <= chars2.length; j++) {
                int cur = dp[j]; // 当前dp[j]的值,在更新dp[j]之前保存它
                if (chars1[i - 1] == chars2[j - 1]) {
                    // 如果字符相等,则当前状态等于左上角状态加1
                    dp[j] = pre + 1;
                } else {
                    // 如果字符不相等,则当前状态等于上方和左方状态的最大值
                    dp[j] = Math.max(dp[j], dp[j - 1]);
                }
                pre = cur; // 更新pre为当前dp[j]的值
            }
        }

        // 返回最终结果,dp[n]即为最长公共子序列长度
        return dp[n] == chars1.length;
    }

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

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

相关文章

GitLab介绍,以及add an SSH key

GitLab GitLab 是一个用于仓库管理系统的开源项目&#xff0c;现今并在国内外大中型互联网公司广泛使用。 git,gitlab,github区别 git 是一种基于命令的版本控制系统&#xff0c;全命令操作&#xff0c;没有可视化界面&#xff1b; gitlab 是一个基于git实现的在线代码仓库…

K8s驱逐场景以及规避方案参考 —— 筑梦之路

Pod 驱逐分为两种情况&#xff1a; 较安全驱逐 & 提高稳定性的良性驱逐 API 发起驱逐&#xff0c;典型案例&#xff1a;kubectl drain Node Not Ready 时&#xff0c;Controller Manager 发起的驱逐 有风险的驱逐 节点压力驱逐 节点磁盘空间不足、内存不足 或 Pid 不足&…

简易Qt串口助手

界面显示如下 关于串口类 初始化 设置串口号 设置波特率 打开串口 发送按钮功能实现 接收数据显示在控件中 关闭串口

Vortex GPGPU的硬件设计和代码结构分析

文章目录 前言一、GPGPU是什么&#xff1f;1.1 GPU和GPGPU之间的差异1.2 GPU和CPU之间的集成方式1.3 GPU包含什么&#xff08;列举和VMIPS向量体系结构的差异&#xff09; 二、Vortex GPGPU是什么&#xff1f;2.1 Vortex GPGPU的技术边界和验证环境2.2 Vortex GPGPU的指令集设计…

30万的剧本杀店 被“好色”店长玩死了

文&#xff5c;琥珀食酒社 作者 | 朱珀 对开店搞钱的人来讲 什么才是最苦逼的&#xff1f; 不是一开始生意就不行 而是刚开始好到不行 最后只剩下不行 本期投稿的主人公糊糊 就是这样的 苦逼大BOSS 30万开剧本杀店 短短几个月 从巅峰跌到谷底 被捞钱又好色的猪队友…

C++ 类和对象 拷贝构造函数

一 拷贝构造函数的概念&#xff1a; 拷贝构造函数是一种特殊的构造函数&#xff0c;用于创建一个对象是另一个对象的副本。当需要用一个已存在的对象来初始化一个新对象时&#xff0c;或者将对象传递给函数或从函数返回对象时&#xff0c;会调用拷贝构造函数。 二 拷贝构造函…

LabVIEW高能质子束流密度分布测试系统

LabVIEW平台开发的高能质子束流密度分布测试系统。该系统主要应用于电子器件的抗辐射加固试验&#xff0c;旨在精确测量高能质子束的密度分布&#xff0c;以评估电子器件在辐射环境下的性能表现和耐受能力。 系统组成与设计 硬件组成&#xff1a; 法拉第杯探测器&#xff1a;…

自动化测试高级控件交互方法:TouchAction、触屏操作、点按,双击,滑动,手势解锁!

在自动化测试领域中&#xff0c;TouchAction 是一种非常强大的工具&#xff0c;它允许我们模拟用户在设备屏幕上的各种触摸事件。这种模拟不仅限于简单的点击操作&#xff0c;还包括滑动、长按、多点触控等复杂的手势。 点按与双击 点按和双击是触屏设备上最基本的操作之一。…

数据库图形化管理界面应用 Navicat Premium 使用教程

经同学介绍的一个把数据库可视化的软件Navicat Premium&#xff0c;很好用&#xff0c;在这里分享一下&#xff0c;需要的同学可以去了解看看 一&#xff1a;下载并解压 链接&#xff1a;https://pan.baidu.com/s/1ZcDH6m7EAurAp_QmXWx81A 提取码&#xff1a;e5f6 解压到合…

景芯SoC训练营DFT debug

景芯训练营VIP学员在实践课上遇到个DFT C1 violation&#xff0c;导致check_design_rule无法通过&#xff0c;具体报错如下&#xff1a; 遇到这个问题第一反映一定是确认时钟&#xff0c;于是小编让学员去排查add_clock是否指定了时钟&#xff0c;指定的时钟位置是否正确。 景芯…

Redis原理-数据结构

Redis原理篇 1、原理篇-Redis数据结构 1.1 Redis数据结构-动态字符串 我们都知道Redis中保存的Key是字符串&#xff0c;value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。 不过Redis没有直接使用C语言中的字符串&#xff0c;因为C语言字符串存…

【操作系统】进程管理——进程的同步与互斥(个人笔记)

学习日期&#xff1a;2024.7.8 内容摘要&#xff1a;进程同步/互斥的概念和意义&#xff0c;基于软/硬件的实现方法 进程同步与互斥的概念和意义 为什么要有进程同步机制&#xff1f; 回顾&#xff1a;在《进程管理》第一章中&#xff0c;我们学习了进程具有异步性的特征&am…

Apache AGE中的图

图由一组点和边组成&#xff0c;其中每个节点和边都具有属性映射。点是图的基本对象&#xff0c;可以独立于图中的其他任何对象存在。边创建了两个点之间的有向连接。 创建图 要创建图&#xff0c;可以使用 ag_catalog 命名空间中的 create_graph 函数。 create_graph() 语法…

C++进阶-二叉树进阶(二叉搜索树)

1. 二叉搜索树 1.1 二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 1.若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值2.若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于…

Jenkins教程-15-常用插件-Blue Ocean

上一小节我们学习了Jenkins定时任务构建的方法&#xff0c;本小节我们讲解一下Jenkins常用插件Blue Ocean的使用方法。 Blue Ocean 提供了一套可视化操作界面来帮助创建、编辑 Pipeline 任务。 Blue Ocean 特性&#xff1a; 流水线编辑器&#xff1a;用于创建贯穿始终的持续交…

一、redis-万字长文读懂redis

高性能分布式缓存Redis `第一篇章`1.1缓存发展史&缓存分类1.1.1 大型网站中缓存的使用带来的问题1.1.2 常见缓存的分类及对比与memcache对比1.2 数据类型选择&应用场景1.2.1 string1.2.2 hash1.2.3 链表1.2.4 set1.2.5 sortedset有序集合类型1.2.6 总结1.3 Redis高级应…

mysql在linux系统下重置root密码

mysql在linux系统下重置root密码 登录服务器时候mysql密码忘记了&#xff0c;没办法只能重置&#xff0c;找了一圈&#xff0c;把行之有效的方法介绍在这里。 错误展示&#xff1a; 我还以为yes就可以了呢&#xff0c;这是不行的意思。 关掉mysql服务 sudo systemctl stop …

百度、谷歌、必应收录个人博客网站

主要是给各个搜索引擎提交你的sitemap文件&#xff0c;让别人能搜到你博客的内容。 主题使用的Butterfly。 生成sitemap 安装自动生成sitemap插件。 npm install hexo-generator-sitemap --save npm install hexo-generator-baidu-sitemap --save在站点配置文件_config.yml…

Redhat 安装 docker 网络连接超时问题

目录 添加阿里云的Docker CE仓库 更新YUM缓存 安装 Docker Engine 启动并设置Docker自启动 验证 Docker 安装 [userlocalhost ~]$ sudo yum-config-manager --add-repohttps://download.docker.com/linux/centos/docker-ce.repo 正在更新 Subscription Management 软件仓库…

PHP中的运算符与表达式:深入解析与实战应用

目录 一、基础概念 1.1 运算符的定义 1.2 表达式的定义 二、PHP运算符的分类 2.1 算术运算符 2.2 赋值运算符 2.3 比较运算符 2.4 逻辑运算符 2.5 位运算符 2.6 字符串运算符 2.7 错误控制运算符 三、表达式的优先级与结合性 3.1 优先级 3.2 结合性 四、实战应…