文章目录
- 一、1312. 让字符串成为回文串的最少插入次数
- 1.题目简介
- 2.解题思路
- 3.代码
- 4.运行结果
- 二、1143. 最长公共子序列
- 1.题目简介
- 2.解题思路
- 3.代码
- 4.运行结果
- 三、1035. 不相交的线
- 1.题目简介
- 2.解题思路
- 3.代码
- 4.运行结果
- 总结
一、1312. 让字符串成为回文串的最少插入次数
1.题目简介
1312. 让字符串成为回文串的最少插入次数
给你一个字符串 s ,每一次操作你都可以在字符串的任意位置插入任意字符。
请你返回让 s 成为回文串的 最少操作次数 。
「回文串」是正读和反读都相同的字符串。
2.解题思路
3.代码
class Solution {
public:
int minInsertions(string s) {
int n = s.size();
//1.判断出字符串中最长回文子序列
vector<int> v(n, 0);
vector<vector<int>> dp(n, v);
//dp[i][j]表示以i为结尾以j为开始的最长回文子序列元素个数
//初始化
for(int i = 0;i < n; ++i)
{
dp[i][i] = 1;
}
for(int i = 0;i < n; ++i)
{
for(int j = i - 1;j >= 0; --j)
{
if(s[i] == s[j])//如果相等,则回文子序列加2元素
{
dp[i][j] = dp[i - 1][j + 1] + 2;
}
else//如果不相等,则它的回文子序列为i或j往前遍历一个位置对应的回文子序列的较大值
{
dp[i][j] = max(dp[i - 1][j], dp[i][j + 1]);
}
}
}
int a = dp[n - 1][0];
//2.用总元素个数减去最长回文子序列的元素个数
return n - a;
}
};
4.运行结果
二、1143. 最长公共子序列
1.题目简介
1143. 最长公共子序列
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
2.解题思路
3.代码
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
vector<int> v(text2.size() + 1, 0);
vector<vector<int>> dp(text1.size() + 1, v);
//dp[i][j]表示以i - 1为结尾的text1字符串和以j - 1为结尾的text2这两个字符串的最长公共子序列(为啥要-1呢?为了方便计算i - 1和j - 1的值,而不用很麻烦的初始化i=0和j=0的情况,实际上就是将i和j作为了长度而不是坐标)
for(int i = 1;i <= text1.size(); ++i)
{
for(int j = 1;j <= text2.size(); ++j)
{
if(text1[i - 1] == text2[j - 1])//如果i和j对应元素相等,就等于它们前一个元素对应的最长长度加一
{
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()];
}
};
4.运行结果
三、1035. 不相交的线
1.题目简介
1035. 不相交的线
在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。
现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足: nums1[i] == nums2[j]
且绘制的直线不与任何其他连线(非水平线)相交。
请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。
以这种方法绘制线条,并返回可以绘制的最大连线数。
2.解题思路
3.代码
class Solution {
public:
int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
vector<int> v(nums2.size() + 1, 0);
vector<vector<int>> dp(nums1.size() + 1, v);
//实际上就是在求:以i为结尾的nums1数组和以j结尾的nums2数组两者之间的最长公共子序列
for(int i = 1;i <= nums1.size(); ++i)
{
for(int j = 1;j <= nums2.size(); ++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()];
}
};
4.运行结果
总结
今天是算法练习的第11天。
长风破浪会有时,直挂云帆济沧海,继续加油。
文中题目来源:力扣(LeetCode),著作权归领扣网络所有。
如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!