記事ディレクトリ
1. 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. 走行結果
2. 1143. 最長共通部分列
1. トピックの紹介
1143. 最長共通部分列
2 つの文字列 text1 と text2 を指定すると、これら 2 つの文字列の最長共通部分列の長さを返します。共通の部分列がない場合は 0 を返します。
文字列のサブシーケンスとは、文字の相対的な順序を変更せずに、一部の文字を削除する (または文字をまったく削除しない) ことによって、元の文字列から構成される新しい文字列を指します。
たとえば、「ace」は「abcde」の部分列ですが、「aec」は「abcde」の部分列ではありません。
2 つの文字列の共通部分シーケンスは、両方の文字列が共通に持つ部分シーケンスです。
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. 走行結果
3. 1035. バラバラな線
1. トピックの紹介
1035. 連続しない行
nums1 と nums2 の整数を、指定された順序で 2 本の独立した水平線に書き込みます。
ここで、2 つの数値 nums1[i] と nums2[j] を結ぶ直線を描くことができます。これらの直線は、同時に nums1[i] == nums2[j] を満たす必要があり、描かれた直線は次の条件を満たしません
。交差する他の線 (水平線ではない) と接続します。
線は端点であっても交差できないことに注意してください。各数値は 1 つの線にのみ属することができます。
この方法で線を描画し、描画できる接続の最大数を返します。
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、著作権は LeetCode Network に属します。
この記事があなたにインスピレーションを与えたなら、著者をもっとサポートしていただければ幸いです。皆さん、ありがとう!