代碼隨想錄算法訓練營|第五十五天|1143.最长公共子序列、1035.不相交的线、53. 最大子序和。刷题心得(c++)

本文主要是介绍代碼隨想錄算法訓練營|第五十五天|1143.最长公共子序列、1035.不相交的线、53. 最大子序和。刷题心得(c++),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

讀題

1143.最长公共子序列

自己看到题目的第一想法

看起來跟最長重複子数組很類似,但是要怎麼去推遞推的狀態沒有想法

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

看完之後,大概釐清了整體想法,可以想成說,因為我們要考慮的是不連續的子序列,所以會分成兩種狀態,一個是不相同,不相同的話需要看之前的序列有沒有重複,之前包括兩個方面,縱向與橫向關係,要取最大的,因為這個緣故,在相同的時候,因為之前的數都考慮過縱向與橫向的關係,可以直接從左上角跟重複子序列一樣,求出該值。 至於初始化的部分,在定義下標時,i、j都設定為i - 1 或者說 1 ~ i ,讓後續的遞推公式以及初始化都可以比較簡便。

1035.不相交的线

自己看到题目的第一想法

看到這題,看到卡哥的提示,觀察過後其實就跟最長的公共子序列一樣,如果有一個子序列是共有的,那最長的公共子序列一定是可以連接最多不相交的線,整體的概念是一致的。

53. 最大子序和

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

其實整體概念跟連續遞增子序有點像,改為將数組變動 dp[i - 1] + nums[i] 以及 nums[i]的差異,看完程式碼後理解上不會太過於困難。

1143.最长公共子序列 - 實作

思路

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

    dp[i][j] 代表 0~ i - 1 的text1 以及 0 ~ j - 1 的text2 最长公共子序列長度為dp[i][j]

  2. 遞推公式

    分成兩種狀態相同與不相同

    不相同的話需要看之前的序列有沒有重複,之前包括兩個方面,縱向與橫向關係,要取最大的

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

    相同的時候,因為之前的數都考慮過縱向與橫向的關係,可以直接從左上角跟重複子序列一樣

    dp[i][j] = dp[i - 1][j - 1] + 1;

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

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

  4. 確定遍歷順序

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

Code

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {vector<vector<int>> dp (text1.size() + 1, vector<int>(text2.size() + 1, 0));for(int i = 1; i < text1.size() + 1; i++) {for(int j = 1; j < text2.size() + 1; j++) {if(text1[i - 1] == text2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}return dp[text1.size()][text2.size()];}
};

1035.不相交的线 - 實作

思路

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

    dp[i][j] 代表 0~ i - 1 的nums1 以及 0 ~ j - 1 的nums2 最长不相交的线為dp[i][j]

  2. 遞推公式

    分成兩種狀態相同與不相同

    不相同的話需要看之前的序列有沒有重複,之前包括兩個方面,縱向與橫向關係,要取最大的

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

    相同的時候,因為之前的數都考慮過縱向與橫向的關係,可以直接從左上角跟重複子序列一樣

    dp[i][j] = dp[i - 1][j - 1] + 1;

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

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

  4. 確定遍歷順序

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

Code

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

53. 最大子序和 - 實作

思路

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

    dp[i] 代表 i 之前包含i 的number[i] 結尾的最大子序和是多少

  2. 遞推公式

    當前的数加上前面的數比較大還是當前的數比較大,取大的。

    dp[i] = max(dp[i - 1] + nums[i], nums[i])

    if dp [i] > result 更新result

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

    將數組初始化為最小值,以及result = nums[0]

  4. 確定遍歷順序

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

Code

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

總結

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

一開始對於最長公共子序列不太了解,但看完講解後,其實就是在重複子序列的基礎上考慮橫向與縱向的關係,以及最大子序和整體很像最長連續子序列,只是思考上需要進行轉換﹐整體而言,今天題目主要是思路上需要做一些改變,不然很容易繞進去。

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

今天大概學習了2hr,整體是很充實的,尤其理解最長公共子序列,在想法上接續到的二題不相交的線就會非常清晰。

相關資料

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

1143.最长公共子序列

视频讲解:动态规划子序列问题经典题目 | LeetCode:1143.最长公共子序列_哔哩哔哩_bilibili

https://programmercarl.com/1143.最长公共子序列.html

1035.不相交的线

视频讲解:动态规划之子序列问题,换汤不换药 | LeetCode:1035.不相交的线_哔哩哔哩_bilibili

https://programmercarl.com/1035.不相交的线.html

53. 最大子序和

视频讲解:看起来复杂,其实是简单动态规划 | LeetCode:53.最大子序和_哔哩哔哩_bilibili

https://programmercarl.com/0053.最大子序和(动态规划).html

这篇关于代碼隨想錄算法訓練營|第五十五天|1143.最长公共子序列、1035.不相交的线、53. 最大子序和。刷题心得(c++)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

关于最长递增子序列问题概述

《关于最长递增子序列问题概述》本文详细介绍了最长递增子序列问题的定义及两种优化解法:贪心+二分查找和动态规划+状态压缩,贪心+二分查找时间复杂度为O(nlogn),通过维护一个有序的“尾巴”数组来高效... 一、最长递增子序列问题概述1. 问题定义给定一个整数序列,例如 nums = [10, 9, 2

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解