每日一题——字母板上的路径

103 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情


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!"

思路

一开始看到这个题,考虑的点在于如何找到最小的行动次数,也就是找到最短的路径,可以使用BFS进行四个方向的遍历,但是字母是有顺序规律的,两个字母之间的差值可以通过上下和左右移动体现出来,故并不会出现字母在下方但向上移动的可能。

其中还有一个难点在于,若我们到达了z位置,我们如何去到达右上方向的位置呢,很显然,这时,我们不需要向左的操作了,故我们需要最后执行向右的操作,同理,我们要想从其他位置到达z位置,我们需要最后执行向下的操作。综上,我们要将右移操作和下移操作放在最后。

题解

class Solution {
    public String alphabetBoardPath(String target) {
        int cx = 0, cy = 0;
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < target.length(); i++) {
            char c = target.charAt(i);
            int nx = (c - 'a') / 5;
            int ny = (c - 'a') % 5;
            if(cx > nx) {
                for(int j = cx; j > nx; j--) {
                    sb.append('U');
                }
            }
            if(cy > ny) {
                for(int j = cy; j > ny; j--) {
                    sb.append('L');
                }
            }
            if(cx < nx) {
                for(int j = cx; j < nx; j++) {
                    sb.append('D');
                }
            }
            if(cy < ny) {
                for(int j = cy; j < ny; j++) {
                    sb.append('R');
                }
            }
            cx = nx;
            cy = ny;
            sb.append('!');
        }
        return sb.toString();
    }
}

如果你有其他的思路或者更好的解法,亦或者你发现了文章出现了错误或有不足,欢迎在评论区和我交流,我看到了一定会回复。

写文章不易,如果你觉得文章对你有帮助,麻烦点一下点赞、收藏,你的支持是我写文章的最大动力!