1138. 字母板上的路径
题目描述
我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。
在本题里,字母板为board = [“abcde”, “fghij”, “klmno”, “pqrst”, “uvwxy”, “z”],如下所示。
我们可以按下面的指令规则行动:
- 如果方格存在,‘U’ 意味着将我们的位置上移一行;
- 如果方格存在,‘D’ 意味着将我们的位置下移一行;
- 如果方格存在,‘L’ 意味着将我们的位置左移一列;
- 如果方格存在,‘R’ 意味着将我们的位置右移一列;
- ‘!’ 会把在我们当前位置 (r, c) 的字符 board[r][c] 添加到答案中。
(注意,字母板上只存在有字母的位置。)
返回指令序列,用最小的行动次数让答案和目标 target 相同。你可以返回任何达成目标的路径。
示例 1
输入:target = “leet”
输出:“DDR!UURRR!!DDD!”
示例 2
输入:target = “code”
输出:“RR!DDRR!UUL!R!”
提示
- 1 <= target.length <= 100
- target 仅含有小写英文字母。
算法一:模拟
思路
- 把字母转换成它在字母版上的位置。由于字母的 ASCII 值是连续的,把字母的 ASCII 值减去 ‘a’ 的 ASCII 值, 就得到了它是第几个字母(从 0 开始),比如 n 是第 13 个, 那么它就在 13 / 5 = 2 行, 第 13 mod 5 = 3 列。
- 用 直角拐弯 来移动 ,‘z’ 字符需要特殊处理,必须先水平移动,再竖直移动,其他字符先竖直移动,再水平移动(这样可以防止上一个字母是 z 的情况)。
收获
- 一开始我先用 BFS 来做,和题解相比显得过于繁琐;
- 我没有想到如何字母转换成它在字母版上的位置 ;
- 水平/竖直的字符串也进行了巧妙处理,比如
string v(abs(nx - x), "UD"[nx > x]);
当 nx > x 时,返回 1 ,即得到 D,向下移动, 当 nx < x 时,返回 0 ,得到 U。
算法情况
- 时间复杂度:O(n),其中 n 为 target 的长度。
- 空间复杂度:O(1)
代码
class Solution {
public:
string alphabetBoardPath(string target) {
string ans;
int x = 0, y = 0;
for(char c : target){
int nx = (c - 'a') / 5, ny = (c - 'a') % 5; // 目标位置
string v(abs(nx - x), "UD"[nx > x]); // 竖直
string h(abs(ny - y), "LR"[ny > y]); // 水平
ans += (c != 'z' ? v + h : h + v) + "!";
x = nx, y = ny;
}
return ans;
}
};