タイトル:
文字列 s
を指定してs
、最長の回文の部分文字列を見つけます 。想定できる s
最大長は1000です。
例1:
入力:「babad」 出力:「bab」 注:「aba」も有効な回答です。
例2:
入力: "cbbd" 出力: "bb"
アイデア:
動的プログラミングを使用して、初期状態:
- dp [i] [i] = 1; //単一の文字は回文文字列です
- dp [i] [i + 1] = 1 if s [i] = s [i + 1]; // 2つの連続する同一の文字が回文文字列
「アババ」の例を考えてみましょう。「bab」が回文であることをすでに知っている場合、「ababa」は左右の文字が同じであるため、回文であることは明らかです。したがって、
dp [i] [j] = dp [i + 1] [j-1] && s [i] == s [j]
複雑さの分析
-
時間の複雑さ:O(n ^ 2)。
-
スペースの複雑さ:O(n ^ 2)、O(n ^ 2)スペースを使用して格納します。
Javaコード:
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if (len == 0 || len == 1) {
return s;
}
//为1表示是回文 默认为0表示不是回文
int[][] dp = new int[len][len];
//回文串的开始位置
int start = 0;
//回文中的最大长度
int max = 1;
for (int k = 2; k <= len; k++) { //l表示检索的子串长度,等于2表示先检索长度为2的子串
for (int i = 0; i + k - 1 < len; i++) {
dp[i][i] = 1;
int j = i + k - 1;//终止字符位置
if (k == 2) {//k=2时,初始化相邻字符是否为回文串
if (s.charAt(i) == s.charAt(j)) {
dp[i][j] = 1;
start = i;
max = 2;
}
} else { //k>2
if (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1] == 1) {
dp[i][j] = 1;
start = i;
max = k;
}
}
}
}
return s.substring(start, start + max);
}
}
限定レベルのため、必然的にブログに間違いがございますので、間違いがありましたらお知らせください!
推奨読書:
[Leetcode- 動的計画 ]階段を上る -CSDNブログ
[Leetcode- 動的計画 ]株式の売買に最適な時期 -CSDNブログ
[Leetcode- 動的プログラミング ]最大サブシーケンス合計
[Leetcode- 動的計画 ]異なるパス -CSDNブログ
【Leetcode- ダイナミック企画】ジャンプゲーム -CSDNブログ
[Leetcode- 動的計画 ]変更の変更 -CSDNブログ