目次
動的プログラミングを学ぶにはどうすればよいですか?
動的プログラミングの学習はもちろん、アルゴリズムの学習にも近道はありません。
私と一緒に動的計画アルゴリズムの質問を解決し、動的計画を一緒に学びましょう!
1. 質問分析
質問リンク: 467. 文字列内の唯一の部分文字列を囲む - LeetCode
この問題も分かりやすく、基本的には一度読めば理解できるので、例を挙げて見てください。
Base には空ではない異なる部分文字列が何個表示されますか? Base は a ~ za ~ z の無限サイクルです。
2. アルゴリズム原理
1.ステータス表示
dp[ i ] は、位置 i で終わるすべての部分文字列のうち、base に出現した個数を表します。
2. 状態遷移方程式
これは次の 2 つの状況に分類できます。
長さが 1 の場合、dp[i] = 1
長さが 1 より大きい場合、i 位置が前の位置と結合されていることが証明されます。
s[ i - 1 ] + 1 == s[ i ] || ( s[ i - 1 ] == 'z' && s[ i ] == 'a' ),dp[ i ] = dp[ i - 1 ]
(以前と同じくらい多くの状況が今も存在します)
求められるのはすべての状況の合計であるため、状態遷移方程式は次のようになります。
dp[ i ] = 1 + s[ i - 1 ] + 1 == s[ i ] || ( s[ i - 1 ] == 'z' && s[ i ] == 'a' ) ? dp[ i ] = dp[ i - 1 ] : 0
3. 初期化
各文字が出現する必要があるため、配列を直接 1 に初期化できます。
このようにして、状態遷移方程式では余分な 1 を追加する必要がありません。
4. フォームに記入する順序
左から右へ。
5. 戻り値
文字は繰り返される可能性があるため、すべての要素の合計を直接返すことはできません。
では、どうやって重みを取り除けばいいのでしょうか?
同じ文字で終わる dp 値の場合は、最大のものに進むことができます。
サイズ 26 の配列を作成し、対応する文字の末尾に最大 dp 値を格納します。
最後に、合計を配列で返します。
3. コードの書き方
class Solution {
public:
int findSubstringInWraproundString(string s) {
int n = s.size();
vector<int> dp(n, 1);
for(int i = 1; i < n; i++) {
if(s[i - 1] + 1 == s[i] || (s[i - 1] == 'z' && s[i] == 'a'))
dp[i] += dp[i - 1];
}
int hash[26] = { 0 };
for(int i = 0; i < n; i++) {
hash[s[i] - 'a'] = max(hash[s[i] - 'a'], dp[i]);
}
int sum = 0;
for(auto e : hash) sum += e;
return sum;
}
};
最後に次のように書きます。
以上がこの記事の内容です、読んでいただきありがとうございます。
何かを得たと感じたら、ブロガーに「いいね! 」を与えることができます。
記事の内容に漏れや間違いがある場合は、ブロガーにプライベートメッセージを送信するか、コメント欄で指摘してください〜