LeetCode破解之机器人

111 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

题目描述

力扣团队买了一个可编程机器人,机器人初始位置在原点(0, 0)。小伙伴事先给机器人输入一串指令command,机器人就会无限循环这条指令的步骤进行移动。指令有两种:

  • U: 向y轴正方向移动一格
  • R: 向x轴正方向移动一格。

不幸的是,在 xy 平面上还有一些障碍物,他们的坐标用obstacles表示。机器人一旦碰到障碍物就会被损毁。

给定终点坐标(x, y),返回机器人能否完好地到达终点。如果能,返回true;否则返回false。

示例 1:

输入:command = "URR", obstacles = [], x = 3, y = 2

输出:true

解释:U(0, 1) -> R(1, 1) -> R(2, 1) -> U(2, 2) -> R(3, 2)。

数学思路

这个题目我的初步思路是:因为在障碍物中,如果横坐标比x大,或者纵坐标比y大,则可以认为是无效的障碍物。有些样例就是需要这点的。我们通过只记录第一个周期内经历过的坐标为First[][]:如果执行了command的第i个指令后,机器人的坐标为(cur_x,cur_y),那么有First[i]={cur_x,cur_y},其中i=0,1,...,command.length()-1。最后用DX和DY记录从(0,0)开始,经历了一个command周期后的横坐标与纵坐标。而且对于某个有效的obstacle(这点由1判断),其坐标为(obx,oby)这样判断它是否在机器人路径上:如果对每一个i(i=0,1,...,command.length()-1),都有以下关系:

image-20220630084533768

那么这个obstacle就不在机器人的路径上。对每一个有效障碍物检验这一点,如果有一个没有满足,就return false。

class Solution {
    public boolean robot(String command, int[][] obstacles, int dx, int dy) {
        int x = 0, y = 0;
        Set<Integer> path = new HashSet<>();
        path.add(0);
        for (char c: command.toCharArray()) {
            if (c == 'U')
                y++;
            else x++;
            path.add(x * 1000 + y);
        }
        int[] d = transfer(dx, dy, x, y);
        if (!path.contains(d[0] * 1000 + d[1])) return false;
        for (int[] ob: obstacles) {
            if (ob[0] > dx || ob[1] > dy) continue;
            int[] tr = transfer(ob[0], ob[1], x, y);
            if (path.contains(tr[0] * 1000 + tr[1])) return false;
        }
        return true;
    }

    private int[] transfer(int dx, int dy, int x, int y) {
        int min = Math.min(dx / x, dy / y);
        return new int[] {dx - min*x, dy-min*y};
    }
}

最后

看到有大佬的思路居然可以0ms,先判断终点 , 终点不可达直接false , 再把障碍物都当做终点来判断,障碍物界限超过终点不考虑 , 障碍物可达说明false 。感觉很相似,就是自己的不能0ms。