電子遊戲 「輻射4」 中,任務 「通向自由」 要求玩家到達名爲 「Freedom Trail Ring」 的金屬錶盤,並使用錶盤拼寫特定關鍵詞才能開門。java
給定一個字符串 ring,表示刻在外環上的編碼;給定另外一個字符串 key,表示須要拼寫的關鍵詞。您須要算出可以拼寫關鍵詞中全部字符的最少步數。dom
最初,ring 的第一個字符與 12:00 方向對齊。您須要順時針或逆時針旋轉 ring 以使 key 的一個字符在 12:00 方向對齊,而後按下中心按鈕,以此逐個拼寫完 key 中的全部字符。編碼
旋轉 ring 拼出 key 字符 key[i] 的階段中:code
示例: 輸入:ring = "godding", key = "gd" 輸出:4 解釋:對於 key 的第一個字符 'g',已經在正確的位置, 咱們只須要 1 步來拼寫這個字符。 對於 key 的第二個字符 'd',咱們須要逆時針旋轉 ring "godding" 2 步使它變成 "ddinggo"。 固然, 咱們還須要 1 步進行拼寫。 所以最終的輸出是 4。 提示: ring 和 key 的字符串長度取值範圍均爲 1 至 100; 兩個字符串中都只有小寫字符,而且都可能存在重複字符; 字符串 key 必定能夠由字符串 ring 旋轉拼出。
class Solution { List<Integer>[] pos = new List[26]; int[][] dp; public int findRotateSteps(String ring, String key) { int n = ring.length(), m = key.length(); for(int i = 0; i < 26; i++) { pos[i] = new ArrayList<>(); } for(int i = 0; i < n; i++) { pos[ring.charAt(i) - 'a'].add(i); } dp = new int[n][m]; for(int i = 0; i < n; i++) { Arrays.fill(dp[i], -1); } return dfs(n, 0, key, 0); } public int dfs(int n, int now, String key, int index) { if(index == key.length()) { return 0; } if(dp[now][index] > 0) { return dp[now][index]; } List<Integer> list = pos[key.charAt(index) - 'a']; int min = 0xfffff; for (Integer one : list) { int dis = 1 + Math.min(Math.abs(now - one), n - Math.abs(now - one)) + dfs(n, one, key, index + 1); if(dis < min) { min = dis; } } dp[now][index] = min; return min; } }