代碼隨想錄算法訓練營|第五十四天|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组。刷题心得(c++)

本文主要是介绍代碼隨想錄算法訓練營|第五十四天|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组。刷题心得(c++),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

讀題

300.最长递增子序列

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

思想上很簡單,dp[i]表示i之前的包括i的numbers[i]節尾的最長上升子序列的長度

並且透過兩層迴圈,一層遍歷全部,一層遍歷到i,透過比較當前dp[i]還是dp[j] + 1哪個比較大,來更新動態規劃的dp數組數據。

674. 最长连续递增序列

自己看到题目的第一想法

稍微將300轉一下就好,dp[i] 改為到i之前的最長連續子序列長度為dp[i],公式轉為假設nums[i] > nums[i - 1] 就將dp[i] 的值改為前一個值的個數 + 1就好了

718. 最长重复子数组

自己看到题目的第一想法

的確比較有難度,要思考如何去找出重複子序列,但是將nums1以及nums2的對應表畫出來後,會發現可以透過左上角的值來看重複度,假設左上角為1,那就代表前一個num2的值與前一個num1的值相等,所以當前的值如果也相等,那就要基於dp[i - 1][j - 1]的值 + 1,雖然這個想法完整了,但是自己對於下標的定義沒有想的很清楚,主要是透過畫圖模擬,找出規律並推出遞推公式。

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

看完之後,發現卡哥的做法比較直覺一點,但要想到比較難,我的想法主要是透過畫圖推出,而卡哥是直接在整體数組框架上往外擴一層,就免除了我在nums1[i] != nums2[j] 需要做的額外操作,兩者都可以通過,只是方法不同而已,下標的定義也讓我之前比較模糊的定義有了清晰的了解。

300.最长递增子序列 - 實作

思路

  1. 定義DP數組以及下標的含意

    dp[i] 代表 i 之前包含i 的number[i] 結尾的最大遞增子序列的長度是多少

  2. 遞推公式

    透過兩層迴圈,一個遍歷numbers.size的數組的長度,一個遍歷到i的長度

    if (number[i] > number[j]) dp[i] = max(dp[i], dp[j] + 1)

  3. 根據遞推公式、題意以及定義,確定DP數組如何初始化

    每個數做為結尾都至少含有一個,所以將數組初始化為1

  4. 確定遍歷順序

    0 到 i 因為需要前面的數據來進行遍歷,所以是由前往後。

    0 到 i - 1 只要都有遍歷到就可以了,往前或往後都沒有關係,但為了方便理解,默認由前往後

Code

class Solution {
public:int lengthOfLIS(vector<int>& nums) {vector<int> dp (nums.size(), 1);int result = 1;for(int i = 1; i < nums.size(); i++ ) {for(int j = 0; j < i; j++) {if(nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);}if(dp[i] > result) result = dp[i];}return result;}
};

 

674. 最长连续递增序列 - 實作

思路

  1. 定義DP數組以及下標的含意

    dp[i] 代表 i 之前包含i 的number[i] 結尾的最長連續遞增子序列的長度是多少

  2. 遞推公式

    if (number[i] > number[i - 1]) dp[i] = dp[i - 1] + 1;

    假設number[i] > number[i - 1] 代表number[i - 1]之前都是連續遞增的,所以加上當前的數

    如果沒有大於,就維持初始化

  3. 根據遞推公式、題意以及定義,確定DP數組如何初始化

    每個數做為結尾都至少含有一個,所以將數組初始化為1

  4. 確定遍歷順序

    0 到 i 因為需要前面的數據來進行遍歷,所以是由前往後。

Code

class Solution {
public:int findLengthOfLCIS(vector<int>& nums) {vector<int> dp (nums.size(), 1);int result = 1;for(int i = 1; i < nums.size(); i++ ) {if(nums[i] > nums[i - 1]) dp[i] = dp[i - 1] + 1;if(dp[i] > result) result = dp[i];}return result;}
};

 

718. 最长重复子数组 - 實作

思路

  1. 定義DP數組以及下標的含意

    dp[i][j] 代表 0~ i 的nums1以及 0 ~ j 的nums2最長連續遞增子序列長度為dp[i][j]

  2. 遞推公式

    if(nums1[i] == nums2[j]) { if(i > 0 && j > 0) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] += 1; }

    假設nums1[i] == nums[j] 其中一個不大於 0 則只加一,如果都大於1 則看左上角的數

  3. 根據遞推公式、題意以及定義,確定DP數組如何初始化

    最少為0,所以初始化為0

  4. 確定遍歷順序

    因為需要左上角的數據來進行遍歷,所以是由前往後。

Code

class Solution {
public:int findLength(vector<int>& nums1, vector<int>& nums2) {vector<vector<int>> dp (nums1.size(), vector<int>(nums2.size(), 0));int result = 0;for(int i = 0; i < nums1.size(); i++) {for(int j = 0; j < nums2.size(); j++) {if(nums1[i] == nums2[j]) {if(i > 0 && j > 0) dp[i][j] = dp[i - 1][j - 1] + 1;else dp[i][j] += 1;}if(dp[i][j] > result) result = dp[i][j];}}return result;}
};

 

總結

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

今天第一次做遞增子序列的題目,一開始先看了題解,後面就是一開始的題目轉換思路,以及最長重複子数組則是用畫圖的方式推出解法。

今日收获,记录一下自己的学习时长

今天大概學了2hr,主要是理解子序列的做法該怎麼做。

相關資料

● 今日学习的文章链接和视频链接

300.最长递增子序列

视频讲解:动态规划之子序列问题,元素不连续!| LeetCode:300.最长递增子序列_哔哩哔哩_bilibili

https://programmercarl.com/0300.最长上升子序列.html

674. 最长连续递增序列

视频讲解:动态规划之子序列问题,重点在于连续!| LeetCode:674.最长连续递增序列_哔哩哔哩_bilibili

https://programmercarl.com/0674.最长连续递增序列.html

718. 最长重复子数组

视频讲解:动态规划之子序列问题,想清楚DP数组的定义 | LeetCode:718.最长重复子数组_哔哩哔哩_bilibili

https://programmercarl.com/0718.最长重复子数组.html

这篇关于代碼隨想錄算法訓練營|第五十四天|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组。刷题心得(c++)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/318947

相关文章

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

C++归并排序代码实现示例代码

《C++归并排序代码实现示例代码》归并排序将待排序数组分成两个子数组,分别对这两个子数组进行排序,然后将排序好的子数组合并,得到排序后的数组,:本文主要介绍C++归并排序代码实现的相关资料,需要的... 目录1 算法核心思想2 代码实现3 算法时间复杂度1 算法核心思想归并排序是一种高效的排序方式,需要用