Day45 力扣动态规划 : 1143.最长公共子序列 |1035.不相交的线 | 53. 最大子序和

news2024/10/6 1:42:20

Day45 力扣动态规划 : 1143.最长公共子序列 |1035.不相交的线 | 53. 最大子序和

  • 1143.最长公共子序列
    • 第一印象
    • 看完题解的思路
    • 实现中的困难
    • 感悟
    • 代码
  • 1035.不相交的线
    • 第一印象
    • 感悟
    • 代码
  • 53. 最大子序和
    • 第一印象
      • dp
      • 递推公式
      • 初始化
      • 遍历顺序
    • 实现中的困难
    • 感悟
    • 代码

1143.最长公共子序列

体会一下本题和 718. 最长重复子数组 的区别
视频讲解:https://www.bilibili.com/video/BV1ye4y1L7CQ
https://programmercarl.com/1143.%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%AD%90%E5%BA%8F%E5%88%97.html

第一印象

这道题就是最长重复子序列的不连续版本了,那道题里我特意明确了一下,重复一定是连续的。

那这道题就不仅仅是dp[i-1][j-1] + 1了,而是找到0~i-1 ,j-1 最大那个了。

这个区别就像最长子序列和最长连续子序列。

我试试

写是写出来了,但是图里的例子就会出现重复的情况:

在这里插入图片描述

我的代码是:

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        //dp
        int[][] dp = new int[text2.length() + 1][text1.length() + 1];
        int result = 0;
        //init

        //func
        for (int j = 1; j < text1.length() + 1; j++) {
            for (int i = 1; i < text2.length() + 1; i++) {
                if (text1.charAt(j - 1) == text2.charAt(i - 1)) {
                    //找前几行
                    for (int m = 0; m < i; m++) {
                        for (int n = 1; n <= j; n++) {
                            dp[i][j] = Math.max(dp[i][j], dp[m][n] + 1);
                            result = Math.max(result, dp[i][j]);
                        }
                    }
                    //找这一行
                    for (int n = 0; n < j; n++) {
                        dp[i][j] = Math.max(dp[i][j], dp[i][n]);
                        result = Math.max(result, dp[i][j]);
                    }
                }
            }
        }

        for(int i = 0; i < text2.length() + 1; i++)  {
            for (int j = 0; j < text1.length() + 1; j++) {
                System.out.print(dp[i][j] + "  ");
            }
            System.out.println();
        }
        return result;
    }
}

感觉不能找之前的最大的那个,比如这个c,在dp[3][3]赋值一次变成3之后,又在dp[5][4] 变成 4了,但其实它只应该操作一次。

也就是text1拿来的元素(外层for循环的元素),每次放到text 2 里去遍历一遍,找有没有自己,有的话就要变长。

但是只能找一个自己,因为拿来的一个元素,最多变长一次,也就是+1,不能在for循环中 +1 两次。

//func
for (int j = 1; j < text1.length() + 1; j++) {
    for (int i = 1; i < text2.length() + 1; i++) {
        if (text1.charAt(j - 1) == text2.charAt(i - 1)) {
            //找前几行
            for (int m = 0; m < i; m++) {
                for (int n = 1; n <= j; n++) {
                    dp[i][j] = Math.max(dp[i][j], dp[m][n] + 1);
                    result = Math.max(result, dp[i][j]);
                }
            }
            //找这一行
            for (int n = 0; n < j; n++) {
                dp[i][j] = Math.max(dp[i][j], dp[i][n] + 1);
                result = Math.max(result, dp[i][j]);
            }
            break;
        }
    }
}

这一部分加上break也是错的。如果再text2里找到了这个元素,并且变长结束了,就结束这个元素。去text1里找下一个。

那我直接看题解吧

看完题解的思路

我的思路是不太正确的。

最长递增子序列是,每次都从0看到i-1,如果 i 比 j 大,就尝试更新dp[i] 。

而这道题不太一样,我们要记住dp数组的含义。

长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]

所以不会出现dp[i][j] 中间 全是 0 的情况。 比如 1 2 5 和 1 2 7 8

到 2 那里长度是2,到5 和 7 那里长度不该是0,而还是 2.才对

所以要对两个元素不相等的情况赋值,这样两个元素相等的时候,也不需要去找最大的那个长度再 +1 了,可以直接dp[i-1][j-1] + 1。

因为不管前一个是不是相同的,都被赋值了,是相同的就是到 2 那里的长度2.

不是相同的就是, 5 和 7 那里的长度 2.

再有另一个需要注意的就是怎么给不相同的时候赋值。比如 a c b 和 a b e f

I到b,j到e的时候不相同了,按理来说应该返回 长度2,因为ab 和ab是相同的。

但是呢如果你看dp[i-1][j] 是 ac和 abe = 1,dp[i][j-1] 是acb和ab = 2.

所以每次应该取这两个更大的一个。也就是虽然我拿你俩不相同,不能让长度 + 1. 但是这个情况的最长长度,可能是 i 的更长,也可能是 j 的更长。

实现中的困难

思路清晰就不难

感悟

感觉子序列问题真的好难。

我没法举一反三啊

代码

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        //dp
        int[][] dp = new int[text1.length() + 1][text2.length() + 1];
        int result = 0;
        //init

        //func
        //一行一行的去更新
        for (int i = 1; i < text1.length() + 1; i++) {
            for (int j = 1; j < text2.length() + 1; j++) {
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    result = Math.max(result, dp[i][j]);
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }

        return  result;
    }
}

1035.不相交的线

其实本题和 1143.最长公共子序列 是一模一样的,大家尝试自己做一做。
视频讲解:https://www.bilibili.com/video/BV1h84y1x7MP
https://programmercarl.com/1035.%E4%B8%8D%E7%9B%B8%E4%BA%A4%E7%9A%84%E7%BA%BF.html

第一印象

我有点想不出来,怎么表示这个线呢。

啊!只有相同元素才会连线,但可能相交。

只有公共子序列,排成了一样的顺序,就不会相交了。

也就是找最大公共子序列。

感悟

悟出来这个,就不用做了,直接改改上一道题的代码了

代码

class Solution {
    public int maxUncrossedLines(int[] nums1, int[] nums2) {
        //dp
        int[][] dp = new int[nums1.length + 1][nums2.length + 1];
        int result = 0;
        //init

        //func
        //一行一行的去更新
        for (int i = 1; i < nums1.length + 1; i++) {
            for (int j = 1; j < nums2.length + 1; j++) {
                if (nums1[i - 1] == nums2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    result = Math.max(result, dp[i][j]);
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return  result;
    }
}

53. 最大子序和

这道题我们用贪心做过,这次 再用dp来做一遍
视频讲解:https://www.bilibili.com/video/BV19V4y1F7b5
https://programmercarl.com/0053.%E6%9C%80%E5%A4%A7%E5%AD%90%E5%BA%8F%E5%92%8C%EF%BC%88%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%EF%BC%89.html

第一印象

说之前拿贪心做过,我都快忘了。啊,是看sum的效果是buff还是debuff,debuff就重新开始选。

dp的话 我试试先。

我做出来了!!!

dp

以 i 为结尾的连续子数组de最大和是dp[i] 。

递推公式

每次比较 是只有自己更大呢?还是自己 + dp[i-1] 更大呢?

其实也就是,dp[i-1] 放的是之前的最大和,如果这个最大和+nums[i] 和nums[i] 相比是debuff(其实也就是 最大和 < 0 就是debuff),那完全可以从nums[i]开始了,没必要要前面的了。

 //如果是debuff,那么就重新开始吧
    if (dp[i - 1] < 0) {
        dp[i] = nums[i];
    } else {
        dp[i] = dp[i - 1] + nums[i];
    }

初始化

dp[0] = nums[0]

遍历顺序

正序

实现中的困难

result 初始化应该是nums[0]

感悟

我太厉害了

代码

class Solution {
    public int maxSubArray(int[] nums) {
        //dp
        int[] dp = new int[nums.length];
        int result = nums[0];
        //init
        dp[0] = nums[0];
        //func
        for (int i = 1; i < dp.length; i++) {
            //如果是debuff,那么就重新开始吧
            if (dp[i - 1] < 0) {
                dp[i] = nums[i];
            } else {
                dp[i] = dp[i - 1] + nums[i];
            }
            result = Math.max(result, dp[i]);
        }
        return result;
    }
}

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

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

相关文章

面试分享 | 护网蓝队面试经验

关于蓝队面试经验 1.自我介绍能力 重要性 为什么将自我介绍能力放在第一位&#xff0c;实际上自我介绍才是面试中最重要的一点&#xff0c;因为护网面试并没有确定的题目&#xff0c;让面试官去提问 更多是的和面试官的一种 “交谈” &#xff0c;面试的难易程度也自然就取决…

C++ —— map 和 multimap

一、map 1.介绍 1. map是关联容器&#xff0c;它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元 素。 2. 在map中&#xff0c;键值key通常用于排序和惟一地标识元素&#xff0c;而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同&am…

二十、泛型(5)

本章概要 边界通配符 编译器有多聪明逆变无界通配符捕获转换 边界 边界&#xff08;bounds&#xff09;在本章的前面进行了简要介绍。边界允许我们对泛型使用的参数类型施加约束。尽管这可以强制执行有关应用了泛型类型的规则&#xff0c;但潜在的更重要的效果是我们可以在…

获取AAC音频的ADTS固定头部信息

文章目录 前言一、AAC音频中的ADTS二、解析ADTS信息1.标准文档中介绍2.解析3.采样率索引和值4.下载AAC标准文档 前言 调试嵌入式设备中播放aac音频的过程中&#xff0c;了解了aac音频格式&#xff0c;记录在此&#xff0c;防止遗忘。 一、AAC音频中的ADTS ADTS&#xff08;Audi…

代码随想录day2

目录 vscode 自定义代码模板Reference vscode 自定义代码模板 select User snippets from Settings on the bottom left corner. select a certain language for example: cpp create your own snippets 格式如下&#xff0c;防着写 第一行"cpp template",模板…

Kubernetes 中 RBAC、ServiceAccount 的区别和联系

Author&#xff1a;rab 目录 前言一、区别二、联系三、案例思考&#xff1f; 前言 首先&#xff0c;Kubernetes (K8s) RBAC (Role-Based Access Control) 和 ServiceAccount 都是 Kubernetes 中用于控制访问权限的两个重要概念&#xff0c;但是它们之间有一些区别和联系。 一…

chatgpt==对接API

来到首页 https://platform.openai.com/docs/overview quickstart turorial 生成API KEY https://platform.openai.com/api-keys 来体验下 setx OPENAI_API_KEY "your-api-key-here" echo %OPENAI_API_KEY% 编写PYTHON代码 pip install --upgrade openai from …

ChatGPT 报错“Sorry, you have been blocked…” 什么原因?如何解决?

原因&#xff1a; 频繁切换节点&#xff0c;使用免费代理&#xff0c;账号被锁定 解决办法&#xff1a; 遇到这种情况&#xff0c;请暂时先关闭代理&#xff08;VPN&#xff09;&#xff0c;停止账号登陆&#xff0c;过段时间或隔天再试&#xff0c;防止账号被封。另外不建议使…

大模型在时间序列预测领域的最新15篇论文

最近在和大佬朋友们交流的时候&#xff0c;发现时间序列领域有一个很有潜力的新方向&#xff1a;大模型时间序列。 大模型可以处理不同类型的时间序列数据&#xff0c;例如文本、图像、音频等&#xff0c;也可以适应不同的时间序列数据的变化和异常情况&#xff0c;有助于提高…

TikTok shop美国小店适合哪些人做?附常见运营问题解答

一、Tiktok shop小店分类 大家都知道&#xff0c;美国小店可以分为5 种&#xff1a; 美国本土个人店: 最灵活&#xff0c;有扶持政策&#xff1b;美国法人企业店&#xff1a;要求高&#xff0c;有扶持政策&#xff1b;美国公司中国人占股店 (ACCU店) : 权重相对低&#xff0c…

文件改名:一次性解决文件名混乱,批量重命名技巧

在日常生活和工作中&#xff0c;我们经常会遇到文件名混乱的问题&#xff0c;例如文件名重复、格式不统一或者文件名错误等。这些问题不仅会给我们带来查找和使用上的困扰&#xff0c;还会影响我们的工作效率。为了解决这些问题&#xff0c;我们可以使用批量重命名技巧&#xf…

配置资源管理

Secret Secret 是用来保存密码、token、密钥等敏感数据的 k8s 资源&#xff0c;这类数据虽然也可以存放在 Pod 或者镜像中&#xff0c;但是放在 Secret 中是为了更方便的控制如何使用数据&#xff0c;并减少暴露的风险。 三种类型&#xff1a; kubernetes.io/service-accoun…

跨境电商中的二手宝藏:二手商品市场的崛起

在数字时代的崛起下&#xff0c;跨境电商已经成为了国际贸易的一个重要组成部分。它为人们提供了机会&#xff0c;能够轻松地购买来自世界各地的新商品。 然而&#xff0c;除了全新的产品&#xff0c;二手商品市场也在跨境电商中崭露头角&#xff0c;为买家和卖家提供全新的机…

第十五章,输入输出流代码

package 例题;import java.io.File;public class 例题1 {public static void main(String[] args) {//创建文件对象File file new File("D:\\Java15-1.docx");//判断&#xff0c;如果该文件存在。exists存在的意思if (file.exists()) {//删除//file.delete();//Syst…

AD9371 Crossbar

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射&#xff1a; AD9371 官方例程之 tx_jesd 与 xcvr接口映射 AD9371 官方例程 时钟间的关系与生成 &#xff1a; AD9371 官方…

springcloud小说阅读网站源码

开发工具&#xff1a; 大等于jdk1.8&#xff0c;大于mysql5.5&#xff0c;nodejs&#xff0c;idea&#xff08;eclipse&#xff09;&#xff0c;vscode&#xff08;webstorm&#xff09; 技术说明&#xff1a; springcloud springboot mybatis vue elementui 功能介绍&…

Unity游戏开发基础组件

Unity2D 相机调整&#xff1a;Projection设置为Orthographic。也就是正交模式&#xff0c;忽视距离。 资源&#xff1a; Sprite&#xff1a;一种游戏资源&#xff0c;在2D游戏中表示角色场景的图片资源 SpriteSheet&#xff1a;切割一张图片为多个Sprite 在Sprite Editor中可以…

Git 入门使用 —— 建库、代码上下传、常用命令

目录 一、Git 入门 1.1 Git简介 1.2 Git安装 1.3 创建码云仓库 二、Git 使用 2.1 git初始化操作 2.2 代码上传 2.3 代码下载 2.4 代码更新 2.4.1 仓库管理者 2.4.1 仓库使用者 三、Git 常用命令 一、Git 入门 1.1 Git简介 Git是一个开源的分布式版本控制系统&am…

Vue3+vite+cesium环境搭建

引言 目前有不少vue3cesium的配置教学&#xff0c;存在以下两个问题&#xff1a; &#xff08;1&#xff09;vue3cli方式&#xff0c;随着项目的迭代&#xff0c;npm run serve 启动调试很慢&#xff1b; &#xff08;2&#xff09;vue3vite 确实能将调试启动提升不少的&…

CloudCompare 技巧五 CSF 体积计算等

42、CSF 原始点云 我这路要的是地面分离出来&#xff0c;所以我选的是Flat 结果如下&#xff1a; 43、点云超欠挖体积计算 结果&#xff1a; 44、 网格表面积体积测量 45、法向量