欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

机器人大冒险(能否到达终点)

程序员文章站 2022-07-15 12:24:40
...

机器人大冒险(能否到达终点)

一、题目

题目来源 LeetCode link

​ 力扣团队买了一个可编程机器人,机器人初始位置在原点(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)。
示例 2:

输入:command = “URR”, obstacles = [[2, 2]], x = 3, y = 2
输出:false
解释:机器人在到达终点前会碰到(2, 2)的障碍物。
示例 3:

输入:command = “URR”, obstacles = [[4, 2]], x = 3, y = 2
输出:true
解释:到达终点后,再碰到障碍物也不影响返回结果。

限制:

2 <= command的长度 <= 1000
command由U,R构成,且至少有一个U,至少有一个R
0 <= x <= 1e9, 0 <= y <= 1e9
0 <= obstacles的长度 <= 1000
obstacles[i]不为原点或者终点

二、解题思路

思路一

暴力解法。(超出内存限制

创建一个二维矩阵,在遍历obstacles,在每个障碍处做标记,然后循环command,遇到障碍,则返回false,最后到达终点则返回true。

思路二

空间复杂度O(1),时间复杂度O(m*n) m为command的长度,n为obstacles的长度

​ 题目要求command是循环走的,则每走一遍的x增加值、y增加值都是相同的。如“RUU",(R向右走,x+1;U向上走,y+1)每走一遍,则x+1,y+2。对于目的地x,y,让机器人先走k轮命令,( k=MIN{x / x_1, y / y_1} ),再走下一轮就到达或者超过目标点了,即走k轮后到达离终点距离只有一轮命令的位置。然后走一轮命令来判断是到达目的点还是超过目的点。

例如:指令 “URR” 执行完毕停留在(2,1)这个点,假若终点是(10000,5001),那么机器人执行 5000 次指令到达终点附近的点(10000,5000),在走下一轮时,就会到达终点。

方法boolean isArrive(String command, int x_0, int y_0, int x_tar, int y_tar)用来判断从点x_0,y_0走一轮command是否到达x_tar,y_tar。

第一步

​ 首先判断是否能到达终点,如果终点都到不了,就不用考虑障碍物了,直接return false。

第二步

​ 遍历obstacles[][] 数组中的每一个障碍物,如果机器人能到达障碍物,则return false。

三、代码

java

public class Rebot {
    public static boolean robot(String command, int[][] obstacles, int x, int y) {
        //x_1,y_1为走过一遍指令后的变化值
        int x_1 = 0, y_1 = 0;
        int k;
        for (int i = 0; i < command.length(); i++) {
            if (command.charAt(i) == 'U') {
                y_1++;
            } else {
                x_1++;
            }
        }
        //k表示走k遍指令
        k = Math.min(x / x_1, y / y_1);
        //x_tar,y_tar代表走过k轮后,剩下的距离
        int x_tar = x - k * x_1;
        int y_tar = y - k * y_1;
        //判断是否能到达终点
        if (!isArrive(command, 0, 0, x_tar, y_tar)) {
            return false;
        }
        //判断障碍物是否在行走路线上
        for (int i = 0; i < obstacles.length; i++) {
            k = Math.min(obstacles[i][0] / x_1, obstacles[i][1] / y_1);
            x_tar = obstacles[i][0] - k * x_1;
            y_tar = obstacles[i][1] - k * y_1;
            //只判断在目标点范围内的障碍物
            if (obstacles[i][0] <= x && obstacles[i][1] <= y && isArrive(command, 0, 0, x_tar, y_tar)) {
                return false;
            }
        }
        return true;
    }

    //判断机器人能否从起始点x_0,y_0到达一个目标点x_tar,y_tar
    //x_1,y_1为当前位置,x,y为目标位置
    public static boolean isArrive(String command, int x_0, int y_0, int x_tar, int y_tar) {
        for (int i = 0; i < command.length(); i++) {
            //判断目标点和起始点是否重合
            if (x_0 == x_tar && y_0 == y_tar) {
                return true;
            }
            //执行一轮命令
            if (command.charAt(i) == 'U') {
                y_0++;
            } else {
                x_0++;
            }
        }
        return false;
    }
}