说白了就是一个密码盘,旋转得到相应密码,求拼得某词汇的最小路径。唯一需要注意是每转到12点方向,摁中间button也算一步,其实就是最后加上keyword长度就好。(假设:1. 密码一定能被拼出 2. 顺时针逆时针都可以转)
Example:
Input: ring = "godding", key = "gd"
Output: 4
Explanation:
For the first key character 'g', since it is already in place, we just need 1 step to spell this character.
For the second key character 'd', we need to rotate the ring "godding" anticlockwise by two steps to
make it become "ddinggo".
Also, we need 1 more step for spelling.
So the final output is 4.
Note:
Length of both ring and key will be in range 1 to 100.
There are only lowercase letters in both strings and might be some duplcate characters in both strings.
It's guaranteed that string key could always be spelled by rotating the string ring.
思路
动态规划,因为凑得最短路径需要“讨价还价”,也就是能化成子问题和递推状态方程。
步骤
- 画DP的表格,用一个例子推倒一遍过程,发现程序逻辑规律。
- 写dp表格格式,分析是2D还是1D,用Boolean[][]还是int[][], 学会用int替代String。
- 循环,可以从后往前循环比较直观对应子问题。
- 记得初始化dp[i][j],Integer.MAX_VALUE or 1 or true.
- 注意比较条件,递推方程怎么依附于子问题。
- 可以打印出dp debug。
- 注意返回值是否符合要求。
- 注意边界情况,array==null or length==0
注意的点
- 不论从后往前还是从前往后,都要预留出一行
代码
i从m-1到0的方法
class Solution {
public int findRotateSteps(String ring, String key) {
int n = ring.length();
int m = key.length();
int[][] dp = new int[m+1][n];
for(int i = m-1;i>=0;i--){
for(int j = 0;j<n;j++){
dp[i][j]=Integer.MAX_VALUE;
for(int k=0;k<n;k++){
if(ring.charAt(k)==key.charAt(i)){
int diff = Math.abs(j-k);
int step = Math.min(diff,n-diff);
dp[i][j] = Math.min(dp[i][j],step+dp[i+1][k]);
}
}
}
}
for(int i=0;i<m+1;i++){
for(int j=0;j<n;j++){
System.out.print(dp[i][j]+", ");
}
System.out.println();
}
/*
2, 3, 4, 5, 5, 4, 3,
2, 1, 0, 0, 1, 2, 3,
0, 0, 0, 0, 0, 0, 0,
*/
// Add m at last, because spelling of each char takes 1 step.
return dp[0][0]+m;
}
}
i从1到m的方法
class Solution {
public int findRotateSteps(String ring, String key) {
int n = ring.length();
int m = key.length();
int[][] dp = new int[m+1][n];
for(int i = 1;i<m+1;i++){
for(int j = 0;j<n;j++){
dp[i][j]=Integer.MAX_VALUE;
for(int k=0;k<n;k++){
if(ring.charAt(k)==key.charAt(m-i)){
int diff = Math.abs(j-k);
int step = Math.min(diff,n-diff);
dp[i][j] = Math.min(dp[i][j],step+dp[i-1][k]);
}
}
}
}
return dp[m][0]+m;
}
}