1. 题目与解析
我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。
在本题里,字母板为board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"],如下所示。
我们可以按下面的指令规则行动:
- 如果方格存在,
'U'意味着将我们的位置上移一行; - 如果方格存在,
'D'意味着将我们的位置下移一行; - 如果方格存在,
'L'意味着将我们的位置左移一列; - 如果方格存在,
'R'意味着将我们的位置右移一列; '!'会把在我们当前位置(r, c)的字符board[r][c]添加到答案中。
(注意,字母板上只存在有字母的位置。)
返回指令序列,用最小的行动次数让答案和目标 target 相同。你可以返回任何达成目标的路径。
输入: target = "leet"
输出: "DDR!UURRR!!DDD!"
输入: target = "code"
输出: "RR!DDRR!UUL!R!"
由于所有的字符在字母板上的位置是固定的,因此从任意字符 aaa 到字符 bbb 的路径也是固定的,我们从中选出一条最短路径即可。两个字符之间的最短距离即等于二者在画板中坐标的曼哈顿距离,可以直接按照“折线”的方式走即可。在考虑时可以先竖向移动,再横向移动
只有一种特殊情况需要考虑,字母z是单独的一行,在竖向移动时,不能移动到没有字母的位置,因此使用一个标记位标记处可能存在的这种情况,单独处理即可。
2. 题解
class Solution {
public String alphabetBoardPath(String target) {
StringBuilder sb = new StringBuilder();
int nowX = 0, nowY = 0;
for (int i = 0; i < target.length(); i++) {
boolean flg = false;
int c = (int)(target.charAt(i) - 'a');
int x = c / 5;
int y = c % 5;
while (x != nowX) {
if (x > nowX) {
if (nowX == 4) {
flg = true;
break;
}
sb.append('D');
nowX++;
} else {
sb.append('U');
nowX--;
}
}
while (y != nowY) {
if (y < nowY) {
sb.append('L');
nowY--;
} else {
sb.append('R');
nowY++;
}
}
if (flg) {
sb.append('D');
nowX++;
}
sb.append('!');
}
return sb.toString();
}
}