举例:
输入: ring = "godding", key = "gd"
输出: 4
/**
* @param {string} ring
* @param {string} key
* @return {number}
*/
var findRotateSteps = function(ring, key) {
// 存储 ring 中每个字母出现的 index
/*{g: [0], o: [1], d: [2, 3], ...}
*/
const indexMap = {}
for(let i = 0; i < ring.length; i++){
const c = ring[i]
if(indexMap[c]){
indexMap[c].push(i)
}else{
indexMap[c] = [i]
}
}
const map = new Map() // 记忆化
function dfs(ringIndex, keyIndex){
const haha = ringIndex * 10000 + keyIndex
if(map.has(haha)){
// 有就直接用
return map.get(haha)
}
// 全都匹配完了
if(keyIndex === key.length){
return 0
}
const current = key[keyIndex] // 当前要匹配的字母
let res = Infinity
for(let item of indexMap[current]){ // 遍历该字母在 ring 中的所有位置
// 顺时针和逆时针转动的距离中较小的
const d1 = Math.abs(item - ringIndex)
const d2 = ring.length - d1
const currentMin = Math.min(d1, d2)
// 下一次递归
res = Math.min(res, currentMin + dfs(item, keyIndex + 1))
}
map.set(haha, res)
return res
}
return dfs(0, 0) + key.length
};