leetcode 1138. 字母板上的路径

80 阅读2分钟

1. 题目与解析

我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]

在本题里,字母板为board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"],如下所示。

image.png

我们可以按下面的指令规则行动:

  • 如果方格存在,'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();
    }
}