代码随想录算法训练营第五十二天|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

代码随想录算法训练营第五十二天|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

最长递增子序列

300.最长递增子序列
文章讲解:https://programmercarl.com/0300.%E6%9C%80%E9%95%BF%E4%B8%8A%E5%8D%87%E5%AD%90%E5%BA%8F%E5%88%97.html
题目链接:https://leetcode.cn/problems/longest-increasing-subsequence/
视频讲解:https://www.bilibili.com/video/BV1ng411J7xP/

自己看到题目的第一想法

没想到好的处理方式。

看完代码随想录之后的想法

列出一张图,如 10 9 2 5 3 7 21这个序列要求最长递增子序列。
在这里插入图片描述

  • 确定dp数组以及其下标含义
    • dp[i]:以nums[i]为结尾的最长连续子序列的长度。
  • 确定递推公式
    • 简单来说就是定义一个i和j,j从0遍历到i-1,然后dp[i]的最大值由j遍历从0到i-1的dp[j]最大值得到,如果nums[i] > nums[j],那dp[i]的最大值就是此刻遍历到的j的dp[j]+1。
  • 确定初始化值
    • 因为每个位置至少有一个自己的数字作为最大值,因此所有的dp[i]的初始值都为1
  • 确定遍历顺序
    • 因为大的值都是由前面小的值推导过来的,因此遍历顺序应该是从前到后
  • 打印数组

自己实现过程中遇到哪些困难

这道题还是相当难理解,后面手写推导了一次状态转移的逻辑就懂了。

public int lengthOfLIS(int[] nums) {int[] dp = new int[nums.length];Arrays.fill(dp,1);int result = dp[0];for(int i = 1; i < nums.length; i++){for(int j = 0; j < i; j++){if(nums[i] > nums[j]){dp[i] = Math.max(dp[i], dp[j] + 1);}}result = Math.max(result,dp[i]);}return result;
}

最长连续递增序列

674. 最长连续递增序列 
文章讲解:https://programmercarl.com/0674.%E6%9C%80%E9%95%BF%E8%BF%9E%E7%BB%AD%E9%80%92%E5%A2%9E%E5%BA%8F%E5%88%97.html
题目链接:https://leetcode.cn/problems/longest-continuous-increasing-subsequence/
视频讲解:https://www.bilibili.com/video/BV1bD4y1778v/

自己看到题目的第一想法

该题和上一题的区别就是本题是连续的。上一题不需要连续。连续和不连续的最大区别就是i只和小一位的j比较,如果比较失败直接为1。
自己写的代码,写完为了验证,还手动推导了一下:

public int findLengthOfLCIS(int[] nums) {int[] dp = new int[nums.length];Arrays.fill(dp,1);int result = dp[0];for(int i = 1; i < nums.length; i++){if(nums[i] > nums[i - 1]){dp[i] = dp[i - 1] + 1;}result = Math.max(result,dp[i]);}return result;}

看完代码随想录之后的想法

这里和我想的一样,只需要比较nums[i]与nums[i - 1],而不用去比较nums[j]与nums[i] (j是在0到i之间遍历)。
既然不用j了,那么也不用两层for循环,一层for循环就行,比较nums[i] 和 nums[i - 1]。

自己实现过程中遇到哪些困难

最长重复子数组

718. 最长重复子数组
文章讲解:https://programmercarl.com/0718.%E6%9C%80%E9%95%BF%E9%87%8D%E5%A4%8D%E5%AD%90%E6%95%B0%E7%BB%84.html
题目链接:https://leetcode.cn/problems/maximum-length-of-repeated-subarray/
视频讲解:https://www.bilibili.com/video/BV178411H7hV/

自己看到题目的第一想法

暴力解法:
两层循环,外层是长度长一点的数组。然后循环遍历nums1,从nums2找到匹配的位置,匹配到了后一起开始向后移动,得到最大值。

动态规划,核心找到递推公式,动态规划五步骤:
dp数组定义:dp[i][j] i表示nums1[i]之前,j表示nums2[j]之前长度最长的子数组。dp[nums1.length -1][nums2.length - 1]就为子数组最长。
递推公式:动态规划没想出来

看完代码随想录之后的想法

动态规划数组定义:

  • 和自己想的类似,dp[i][j]表示以i-1为尾的nums1和以j-1为尾的num2的最长重复子数组的长度。
  • 递推公式if(nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
  • 初始化值,如果这里用dp[i][j]用以i结尾的nums1和以j为尾的nums2的最长重复子数组的话就需要做两次遍历取dp[0][j],dp[i][0]。而这里用i-1,j-1则免去了计算初始值的流程,因为当i=0、j=0时,i-1,j-1无意义,所以直接初始化成0

自己实现过程中遇到哪些困难

dp数组的初始化大小以及循环遍历的次数没处理好,循环的终止条件应该为i <= nums1.length、j <= nums2.length,因为第0位是无意义的值,且比较的是**nums1[i - 1] == nums2[j - 1]**实际要取到nums1.length的位置才能遍历完所有的值。

public int findLength(int[] nums1, int[] nums2) {int[][] dp = new int[nums1.length + 1][nums2.length + 1];// dp数组定义 dp[i][j]:用nums1的i-1位置为结尾以及nums2的j-1为结尾的最长子数组长度int result = 0;for(int i = 1; i <= nums1.length; i++){for(int j = 1; j <= nums2.length; j++){// 推导公式,如果每个数字的位数都相等,则长度加一if(nums1[i - 1] == nums2[j - 1]){dp[i][j] = dp[i - 1][j - 1] + 1;result = Math.max(dp[i][j],result);}}}return result;
}

今日收获&学习时长

子序列问题这三题的关键是确定dp数组的定义,这个非常关键。
第一题最长递增子序列,dp数组的定义使用以nums[i]为结尾的最长连续子序列的长度来表示。然后再用j来表示0-i-1的最长子序列,若nums[i] > nums[j],则dp[i] = dp[j] + 1;
第二题最长连续递增子序列和第一题差不多,但是不需要做2次循环,只需要做一次循环然后和i-1比较即可。
第三题最长重复子数组,这道题的核心也是确定dp数组定义,和上面题目差不多,都是用取nums[i],取nums[j]为结尾做dp数组定义。然后再根据题目要义,连续子数组来做匹配。

整体耗时较长,但是都理解了题目。后续二刷

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

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

相关文章

Android 13.0仿ios的hotseat效果修改hotseat样式

1.概述 在13.0系统产品rom定制化开发中,在项目需求的需要,系统原生Launcher的布局样式很一般,所以需要重新设计ui对布局样式做调整,产品在看到 ios的hotseat效果觉得特别美观,所以要仿ios一样不需要横屏铺满的效果 居中显示就行了,所以就要看hotseat的具体布局显示了 效…

【MATLAB】CEEMD+FFT+HHT组合算法

代码原理 CEEMD&#xff08;集合经验模态分解&#xff09;FFT&#xff08;快速傅里叶变换&#xff09;HHT&#xff08;希尔伯特-黄变换&#xff09;组合算法也是一种常见的信号处理和分析方法。这种组合算法结合了CEEMD、FFT和HHT三个步骤&#xff0c;可以处理非线性和非平稳信…

react中概念性总结(三)

目录 React中事件绑定函数的方法有哪些? 函数如何传递参数&#xff1f; 什么是重绘与回流&#xff0c;触发条件&#xff0c;如何减少回流和重绘 React 生命周期中 getDerivedStateFromProps怎么使用&#xff0c;怎么理解&#xff1f; React中路由单页面应用的优缺点都有哪些…

Vue3+Vite项目搭建

为什么选择vite而不是vue-cli&#xff1a; vite下一代前端开发与构建工具 vite创建的项目默认vue3 优势&#xff1a; 开发环境中&#xff0c;无需打包&#xff0c;可快速的冷启动 轻量快速的热重载&#xff08;HMR&#xff09; 真正的按需编译&#xff0c;不在等待整个应用…

Android中两种选择联系人方式

1.在选择联系人方式网上也有很多案例 有的说是使用ContactsContract.CommonDataKinds.Phone.CONTENT_URI也有的说是使用ContactsContract.Contacts.CONTENT_URI其实这两种方式都可以使用 只不过ContactsContract.Contacts.CONTENT_URI这种方式需要多查询一遍 一、使用Contacts…

23. 合并 K 个升序链表(递归分治)

这是我的第一个自己ak的分治题目&#xff01;&#xff01;&#xff01;好耶&#xff01;&#xff01;&#xff08;骄傲脸 思路参考&#xff1a;148. 排序链表&#xff08;归并排序&#xff09; /*** Definition for singly-linked list.* public class ListNode {* int v…

龙芯系统部署Elasticsearch

1.配置JDK环境 #查看是否安装jdk java -version#搜索java&#xff0c;结果&#xff1a;/usr/bin/java whereis java#&#xff08;1&#xff09;配置环境变量(临时有效) export JAVA_HOME/usr export PATH$PATH:$JAVA_HOME/bin#&#xff08;2&#xff09;配置环境变量(永久有效…

DA14531-高级应用篇-用户如何开启OTA服务

文章目录 1. OTA相关文件2.OTA宏定义列表3.OTA主要函数接口4.OTA具体实施步骤5.总结1. OTA相关文件 1)app_suotar_task.c和app_suotar_task.h 2)app_suotar.c和app_suotar.h 2.OTA宏定义列表 宏定义注解CFG_PRF_SUOTAR用户开启SOTA功能BLE_SUOTA_RECEIVERSOTA功能服务CFG_S…

把树状数组在页面显示成‘/‘/‘形式,并搜索想要的值

大概思路 在Vue中&#xff0c;若要将树状数组以类似于文件路径的形式&#xff08;即“/”分隔&#xff09;显示在页面上&#xff0c;可以按照以下步骤操作&#xff1a; 首先&#xff0c;假设您有一个树状数组&#xff0c;其结构可能如下所示&#xff1a; const treeData [{…

浅谈专项测试之弱网络测试

一&#xff0e;弱网络测试背景 移动端产品的使用并非完全都是在流畅的wifi环境&#xff0c;大部分用户主要使用4G,3G,2G等网络&#xff0c;另外因为移动端产品使用的场景多变&#xff0c;如进公交&#xff0c;上地铁&#xff0c;坐电梯&#xff0c;使得弱网测试显得尤为重要。考…

QT-JSON相关API/QJsonDocument/QJsonObject

QJsonObject类的相关操作 格式化排版创建JSON对象&#xff0c;使用字符串创建JSON对象&#xff0c;使用标准JSON对象获取JSON对象中的值&#xff0c;非数组获取JSON对象中的值&#xff0c;数组 格式化排版 下面的代码将一个符合JSON格式的字符串&#xff0c;格式化成具有缩进格…

HCIA基础知识

IP地址、静态路由、动态路由、交换机 OSPF RIP DHCP VLAN ACL NAT OSI TCP/IP UDP TCP 三次握手&#xff0c;四次挥手&#xff0c;报头 什么是网络&#xff1f; 由网络连接设备通过传输介质将网络终端设备连接起来&#xff0c;进行资源共享、信息传递的平台。 OSI七…

【C】函数指针 int (*addPtr)(int, int);

目录 函数指针1&#xff09;定义2&#xff09;声明和赋值3&#xff09;通过函数指针调用函数4&#xff09;用途&#xff1a;函数指针作为函数参数5&#xff09;函数名和函数指针6&#xff09;复杂一点的例子 函数指针 1&#xff09;定义 在C语言中&#xff0c;函数指针是指向…

智慧校园云桌面解决方案应用场景

​​​​​​教师办公解决方案 教师办公桌面现状 大多数学校一位教师配置一台个人计算机,实际上每位教师平时会使用到的计算机资源不超过15-20%,因此多数时间个人计算机都是处在闲置状态。教师常用的办公用机一般都使用台式机,所有的数据都存放在本地(“信息孤点”),根…

如何购买腾讯云服务器?图文教程超详细

腾讯云服务器购买流程很简单&#xff0c;有两种购买方式&#xff0c;直接在官方活动上购买比较划算&#xff0c;在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵&#xff0c;但是自定义购买云服务器CPU内存带宽配置选择范围广&#xff0c;活动上购买只能选择固定的活动…

​MyBatisPlus的批量插入方法saveBatch时速度缓慢​

一、场景描述 项目组在使用MyBatisPlus的批量插入方法saveBatch时速度缓慢&#xff0c;插入1w条数据&#xff0c;需要近1分钟的时间。 二、解决方案 解决方案很简单&#xff0c;在数据库配置的uri后面加上下面这个属性即可&#xff1a; urlxxxxxxxxxxxxxxxxxxxxxx?rewriteB…

2024年学鸿蒙开发就业前景怎么样?

随着科技的不断进步&#xff0c;鸿蒙系统作为华为自主研发的操作系统&#xff0c;逐渐引起了人们的关注。 2024年&#xff0c;鸿蒙开发就业前景如何&#xff1f; 对于那些对鸿蒙开发感兴趣并希望在这一领域寻找职业发展的人来说&#xff0c;这是一个非常重要的问题。 首先&a…

【cuda】三、矩阵相乘与coalescing writes(合并写操作)

Matrix Multiplication and Optimization 线程块 功能 并行执行&#xff1a;线程块是一组同时执行的线程。它们共同执行分配给它们的任务资源共享&#xff1a;线程块内的线程可以共享数据和同步执行。通过共享内存&#xff08;Shared Memory&#xff09;和同步原语&#xff…

[渗透测试学习] Hospital - HackTheBox

文章目录 信息搜集getshell提权信息搜集 nmap扫描一下端口 发现8080端口和443端口有http服务 然后发现3389端口是启用了ms-wbt-server服务 在对443端口的扫描没有收获,并且只有邮箱登录界面无法注册 接着看向8080端口,我们随便注册用户登录后发现有文件上传功能 getshell …

Python科学计算进阶:数值积分与微分求解算法应用在Python

在Python中进行科学计算时&#xff0c;数值积分和微分是非常常见的操作。下面我将介绍几种常用的数值积分和微分求解算法&#xff0c;并给出Python代码示例。 一、数值积分 矩形法 矩形法是一种简单的数值积分方法&#xff0c;它使用矩形近似代替被积函数。这种方法虽然简单&a…