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

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;
    }
}

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

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

相关文章

Docker:自定义镜像

Docker&#xff1a;自定义镜像 1. 自定义镜像2.实际操作 1. 自定义镜像 我们在通过Dockerfile编写之后&#xff0c;可以通过命令来构建镜像。 2.实际操作 首先&#xff0c;我们将课前资料提供的docker-demo.jar包以及Dockerfile拷贝到虚拟机的/root/demo目录&#xff1a; Do…

【微服务】API治理发展历史与未来趋势

目录 一、前言 二、API治理的价值和意义 2.1 API治理概念 2.2 API治理价值和意义 2.2.1 提升团队协同效率 2.2.2 降低产品运维成本 2.2.3 识别和降低系统的外部风险 2.2.4 提供更多的拓展性 三、API生命周期管理 ​编辑 3.1 规划阶段 3.2 开发阶段 3.3 测试阶段 3…

自动驾驶算法(九):多项式轨迹与Minimun Snap原理与Matab代码详解

目录 1 为什么需要轨迹优化 2 代码解析 3 完整代码 1 为什么需要轨迹优化 我们利用前八篇所学的博客可以利用RRT、A*、遗传算法等设计出一条折线轨迹&#xff0c;轨迹优化就是在路径优化的基础上将折线优化成曲线&#xff0c;这样更加有利于无人机的飞行。 那么什么是多项式轨…

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

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

Google play的企业开发者账号比个人号上包成功率更高?

众所周知&#xff0c;Google play作为全球最大的Android应用市场&#xff0c;是开发者们推广应用的首选平台。Google play平台提供了两种账号类型&#xff1a;个人开发者和企业开发者&#xff0c;开发者们可以选择创建个人开发者账号或者企业开发者账号进行应用上架。 不过&am…

YOLO目标检测——汽车头部尾部检测数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;用于训练自动驾驶系统中的车辆感知模块&#xff0c;以实现对周围车辆头部和尾部的准确检测和识别数据集说明&#xff1a;汽车头部尾部检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软…

linux软链接和硬链接

1.硬链接(hard link) 每个文件的磁盘存储位置都有一个指针指向他这个指针称为inode&#xff0c;每创建一个硬链接都是指向这个inode指针&#xff0c;而不是指向这个文件的物理磁盘位置。 当有多个硬链接指向同一个inode&#xff0c;删除其中一个硬链接文件&#xff0c;他的物理…

键盘win键无法使用,win+r不生效、win键没反应、Windows键失灵解决方案(亲测可以解决)

最近几天发现自己笔记本的win键无法使用&#xff0c;win失灵了&#xff0c;但是外接键盘后则正常:。 这个问题困扰了我一周&#xff0c;我都以为自己的枪神坏了。 寻找了几个解决方法&#xff0c;网上看了好多好多稀里糊涂的办法&#xff0c;都是不管用的&#xff0c;这里给大…

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

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

MySQL 8.0 Clone Plugin 详解

文章目录 前言1. 克隆插件安装2. 克隆插件的使用2.1 本地克隆2.2 远程克隆 3. 克隆任务监控4. 克隆插件实现4.1 Init 阶段4.2 File Copy4.3 Page Copy4.4 Redo Copy4.5 Done 5. 克隆插件的限制6. 克隆插件与 Xtrabackup 的异同7. 克隆插件相关参数 后记 前言 克隆插件&#xf…

JS点击图片指定对象变色两种方法

要求&#xff1a;点击上面的颜色实现下面的图像变成相同的颜色 难点&#xff1a;对于js函数的this对象不太清楚如何传递 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>changeColor</title>&l…

vite基础学习笔记:13.Dialog 对话框 (用户注册与登录)

说明&#xff1a;自学做的笔记和记录&#xff0c;如有错误请指正 1. Dialog 对话框组件 目标效果&#xff1a;点击“登录/注册”&#xff0c;弹框 &#xff08;1&#xff09;创建全局组件&#xff0c;在官网中查询代码粘贴 &#xff08;2&#xff09; 注册和使用全局组件 &a…

Zotero从安装到使用再到插件下载【适合小白,只看一篇就够!!!】

一、安装 1.安装Zotero 本人安装的是zotero6&#xff0c;全文是基于zotero6功能的介绍&#xff01; 下载地址&#xff1a;Zotero下载 选择 Custom&#xff0c;因为Standard是标准型会默认放置C盘&#xff0c;并且不能更改&#xff01; 选择自己的路径进行安装&#xff01;…

创建asp.net core mvc项目

一、安装vs2019 百度搜索【visual studio社区版下载】&#xff0c;进入微软官网 二、安装环境 运行vs2019,点击“工具”->“获取工具和功能” 三、打开vs2019 1.“文件”->“新建”->“项目”-> “ASP.Net Core Web 应用&#xff08;模型-视图-控制器&#xff09…

Python TCP服务端多线程接收RFID网络读卡器上传数据

本示例使用设备介绍&#xff1a;WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com) #python通过缩进来表示代码块&#xff0c;不可以随意更改每行前面的空白&#xff0c;否则程序会运行错误&#xff01;&#xff01;&#xff01;如果缩进不…

Git->git简介,git的常用命令,git命令的常用理论

git简介git的常用命令git命令的常用理论 1.git简介 Git是什么&#xff1f; Git是一个开源的分布式&#xff0c;用于敏捷高效地处理任何或小或大的项目 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVSI…

2023-11 | 短视频批量下载/爬取某个用户的所有视频 | Python

这里以鞠婧祎的个人主页为demo https://www.douyin.com/user/MS4wLjABAAAACV5Em110SiusElwKlIpUd-MRSi8rBYyg0NfpPrqZmykHY8wLPQ8O4pv3wPL6A-oz 【2023-11-4 23:02:52 星期六】可能后面随着XX的调整, 方法不再适用, 请注意 找到接口 找到https://www.douyin.com/aweme/v1/web/…

蓝桥云课--1014 第 1 场算法双周赛

2-数树数【算法赛】&#xff08;找规律&#xff09; 一、题目要求 二、思路 由此可以推导出来&#xff0c;当s[i]L时&#xff0c;下一个编号当前编号*2-1&#xff1b;当s[i]R时&#xff0c;下一个编号当前编号*2&#xff1b; 三、代码 #include<bits/stdc.h> #define…

安卓三防手持终端 二维码扫描识别器 pda条码手持机

PDA条码手持机是一种快速的数据采集设备&#xff0c;具备多种数据采集功能并且可以进行二次开发&#xff0c;可以针对性的进行定制服务&#xff0c;满足各种业务需求。因其体积小&#xff0c;易操作、功能全、效率高深受物联网行业的青睐。 条码扫描是PDA重要的功能之一&#…

网络安全(黑客)小白自学

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高&#xff1b; 二、则是发展相对成熟…