514. 自由之路
視訊遊戲“輻射4”中,任務“通向自由”要求玩家到達名為“Freedom Trail Ring”的金屬錶盤,並使用錶盤拼寫特定關鍵詞才能開門。
給定一個字串 ring,表示刻在外環上的編碼;給定另一個字串 key,表示需要拼寫的關鍵詞。您需要算出能夠拼寫關鍵詞中所有字元的最少步數。
最初,ring 的第一個字元與12:00方向對齊。您需要順時針或逆時針旋轉 ring 以使 key 的一個字元在 12:00 方向對齊,然後按下中心按鈕,以此逐個拼寫完 key 中的所有字元。
旋轉 ring 拼出 key 字元 key[i]
- 您可以將 ring 順時針或逆時針旋轉一個位置,計為1步。旋轉的最終目的是將字串 ring 的一個字元與 12:00 方向對齊,並且這個字元必須等於字元 key[i] 。
- 如果字元 key[i] 已經對齊到12:00方向,您需要按下中心按鈕進行拼寫,這也將算作 1 步。按完之後,您可以開始拼寫 key 的下一個字元(下一階段), 直至完成所有拼寫。
示例:
輸入: ring = "godding", key = "gd" 輸出:4 解釋: 對於 key 的第一個字元 'g',已經在正確的位置, 我們只需要1步來拼寫這個字元。 對於 key 的第二個字元 'd',我們需要逆時針旋轉 ring "godding" 2步使它變成 "ddinggo"。 當然, 我們還需要1步進行拼寫。 因此最終的輸出是 4。
提示:
- ring 和 key 的字串長度取值範圍均為 1 至 100;
- 兩個字串中都只有小寫字元,並且均可能存在重複字元;
- 字串 key 一定可以由字串 ring 旋轉拼出。
class Solution {
public:
int findRotateSteps(string ring, string key) {
int n = ring.size(), m = key.size();
vector<vector<int>> dp(m + 1, vector<int>(n));
for (int i = m - 1; i >= 0; --i) {
for (int j = 0; j < n; ++j) {
dp[i][j] = INT_MAX;
for (int k = 0; k < n; ++k) {
if (ring[k] == key[i]) {
int diff = abs(j - k);
int step = min(diff, n - diff);
dp[i][j] = min(dp[i][j], step + dp[i + 1][k]);
}
}
}
}
return dp[0][0] + m;
}
};