**输入:** ring = "godding", key = "godding"
**输出:** 13
提示:
1 <= ring.length, key.length <= 100
ring 和 key 只包含小写英文字母
保证 字符串 key 一定可以由字符串 ring 旋转拼出
方法一:动态规划
定义 dp}[i][j] 表示从前往后拼写出 key 的第 i 个字符, ring 的第 j 个字符与 12:00 方向对齐的最少步数(下标均从 0 开始)。
显然,只有当字符串 ring 的第 j 个字符需要和 key 的第 i 个字符相同时才能拼写出 key 的第 i 个字符,因此对于 key 的第 i 个字符,需要考虑计算的 ring 的第 j 个字符只有 key}[i] 在 ring 中出现的下标集合。我们对每个字符维护一个位置数组 pos}[i],表示字符 i 在 ring 中出现的位置集合,用来加速计算转移的过程。
funcfindRotateSteps(ring string, key string)int { const inf = math.MaxInt64 / 2 n, m := len(ring), len(key) pos := [26][]int{} for i, c := range ring { pos[c-'a'] = append(pos[c-'a'], i) } dp := make([][]int, m) for i := range dp { dp[i] = make([]int, n) for j := range dp[i] { dp[i][j] = inf } } for _, p := range pos[key[0]-'a'] { dp[0][p] = min(p, n-p) + 1 } for i := 1; i < m; i++ { for _, j := range pos[key[i]-'a'] { for _, k := range pos[key[i-1]-'a'] { dp[i][j] = min(dp[i][j], dp[i-1][k]+min(abs(j-k), n-abs(j-k))+1) } } } return min(dp[m-1]...) }
funcmin(a ...int)int { res := a[0] for _, v := range a[1:] { if v < res { res = v } } return res }
funcabs(x int)int { if x < 0 { return -x } return x }
intfindRotateSteps(char* ring, char* key) { int n = strlen(ring), m = strlen(key); int pos[26][n], posSize[26]; memset(posSize, 0, sizeof(posSize)); for (int i = 0; i < n; ++i) { int x = ring[i] - 'a'; pos[x][posSize[x]++] = i; } int dp[m][n]; memset(dp, 0x3f3f3f3f, sizeof(dp)); for (int i = 0; i < posSize[key[0] - 'a']; i++) { int x = pos[key[0] - 'a'][i]; dp[0][x] = fmin(x, n - x) + 1; } for (int i = 1; i < m; ++i) { for (int j = 0; j < posSize[key[i] - 'a']; ++j) { int x = pos[key[i] - 'a'][j]; for (int k = 0; k < posSize[key[i - 1] - 'a']; ++k) { int y = pos[key[i - 1] - 'a'][k]; dp[i][x] = fmin(dp[i][x], dp[i - 1][y] + fmin(abs(x - y), n - abs(x - y)) + 1); } } } int ret = dp[m - 1][0]; for (int i = 1; i < n; ++i) { ret = fmin(ret, dp[m - 1][i]); } return ret; }
复杂度分析
时间复杂度:O(mn^2),其中 m 为字符串 key 的长度,n 为字符串 ring 的长度。一共有 O(mn) 个状态要计算,每次转移的时间复杂度为 O(n),因此时间复杂度为 O(mn^2)。 由于维护了位置数组 pos 加速了状态的计算与转移,因此 O(mn^2) 是一个较松的上界,很多情况下的时间复杂度都会低于 O(mn^2)。