最近刚考完算法设计分析课的考试,复习总结一下期末考试的几道算法题吧
目录
LCR 095. 最长公共子序列
300. 最长递增子序列
53. 最大子数组和
LCR 100. 三角形最小路径和
矩阵连乘问题
0-1背包
LCR 095. 最长公共子序列
给定两个字符串
text1
和text2
,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回0
。一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
- 例如,
"ace"
是"abcde"
的子序列,但"aec"
不是"abcde"
的子序列。两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
示例 1:
输入:text1 = "abcde", text2 = "ace" 输出:3 解释:最长公共子序列是 "ace" ,它的长度为 3 。示例 2:
输入:text1 = "abc", text2 = "abc" 输出:3 解释:最长公共子序列是 "abc" ,它的长度为 3 。示例 3:
输入:text1 = "abc", text2 = "def" 输出:0 解释:两个字符串没有公共子序列,返回 0 。
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(); i++){for(int j = 1; j <= text2.size(); j++){if(text1[i-1] == text2[j-1])dp[i][j] = dp[i-1][j-1] + 1;elsedp[i][j] = max(dp[i-1][j], dp[i][j-1]);}}return dp[text1.size()][text2.size()];}
};
300. 最长递增子序列
给你一个整数数组
nums
,找到其中最长严格递增子序列的长度。子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,
[3,6,2,7]
是数组[0,3,1,6,2,2,7]
的子序列
。示例 1:
输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。示例 2:
输入:nums = [0,1,0,3,2,3] 输出:4示例 3:
输入:nums = [7,7,7,7,7,7,7] 输出:1提示:
1 <= nums.length <= 2500
-104 <= nums[i] <= 104
遍历一次数组,当访问到i位置元素时,要对 i 位置前面所有 j 位置元素进行遍历访问,若 j 元素小于 i 元素(能够组成一个上升序列)时,对dp数组进行维护更新,从j遍历到i,维护一个能够构成最大序列的数放入dp数组存储。
dp数组中每一个元素都表示当前位置可以组成最大的上升子序列的元素个数。
class Solution {
public:int lengthOfLIS(vector<int>& nums) {vector<int> dp(nums.size(), 1);int res = 1; // 注意初始化res的值、初始条件最小字符串长度为1for(int i = 1; i < nums.size(); i++){for(int j = 0; j < i; j++){if(nums[j] < nums[i]){dp[i] = max(dp[j] + 1, dp[i]);}}res = max(res, dp[i]); // 在每轮遍历数组元素维护一个最大的res值}return res;}
};
53. 最大子数组和
给你一个整数数组
nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和子数组是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。示例 2:
输入:nums = [1] 输出:1示例 3:
输入:nums = [5,4,-1,7,8] 输出:23提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
class Solution {
public:int maxSubArray(vector<int>& nums) {vector<int> dp(nums.size()+1, 0);int res = nums[0];for(int i = 1; i <= nums.size(); i++){ // 每一个位置分为 留数组中元素 或者 不留数组中的元素// 俩种情况中选择一个max值dp[i] = max(dp[i-1] + nums[i-1], nums[i-1]);// 用res来维护dp中的最大值res = max(dp[i], res);}return res;}
};
LCR 100. 三角形最小路径和
给定一个三角形
triangle
,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标
i
,那么下一步可以移动到下一行的下标i
或i + 1
。示例 1:
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]] 输出:11 解释:如下面简图所示:23 46 5 7 4 1 8 3 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。示例 2:
输入:triangle = [[-10]] 输出:-10提示:
1 <= triangle.length <= 200
triangle[0].length == 1
triangle[i].length == triangle[i - 1].length + 1
-104 <= triangle[i][j] <= 104
class Solution {
public:int minimumTotal(vector<vector<int>>& triangle) {// F[i,j] = triangle[row-1][j]int row = triangle.size();for(int i = row-2; i >= 0; --i){for(int j = 0; j < triangle[i].size(); ++j){triangle[i][j] = min(triangle[i+1][j],triangle[i+1][j+1])+triangle[i][j];}}return triangle[0][0];}
};
矩阵连乘问题
0-1背包