LC - P03 机器人大冒险

本文探讨了机器人在给定指令和障碍物的情况下,能否到达指定坐标的路径规划问题。提出了两种解题策略,一种是直接模拟移动过程,但时间复杂度过高;另一种是优化后的解法,通过判断目标点及障碍物的可达性来高效解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

机器人大冒险

题目描述

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

  1. U: 向y轴正方向移动一格;
  2. 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
  • commandU,R构成,且至少有一个U,至少有一个R
  • 0 <= x <= 1e9, 0 <= y <= 1e9
  • 0 <= obstacles的长度 <= 1000
  • obstacles[i]不为原点或者终点。

解题思路

个人AC

模拟机器人的移动过程,最终会超时。

func robot(commands string, obstacles [][]int, x int, y int) bool {
    for i, j := 0, 0; x >= i && y >= j; {
        command := commands[(i + j) % len(commands)]
        if command == 'U' {
            j++
        } else {
            i++
        }
        for _, obstacle := range obstacles {
            if obstacle[0] == i && obstacle[1] == j {
                return false
            }
        }
        if i == x && j == y { // arrive the destination
            return true
        }
    }
    return false
}

时间复杂度: O ( ( x + y ) ∗ l e n ( o b s t a c l e s ) ) O((x + y) * len(obstacles)) O((x+y)len(obstacles))

最优解

只需要对目标点(x, y)以及所有obstacle进行可达性判断:

  1. 如果(x, y)不可达,直接返回false
  2. 遍历obstacles,只要有一个obstacle可达,则返回fasle(否则视为无效障碍);
  3. 否则返回true

那么如何判断一个点是否可达呢?

  1. 先计算从(0, 0)移动到(x, y)需要的步数:steps := x + y
  2. 然后计算在这些步数中RU的数量,只有RU的数量分别等于xy时,这个点才是可达的。
func robot(command string, obstacles [][]int, x int, y int) bool {
    if !canArrive(command, x, y) {
        return false
    }
    for _, o := range obstacles {
        if ((x + y) > (o[0] + o[1])) && canArrive(command, o[0], o[1]) {
            return false
        }
    }
    return true
}

func canArrive(command string, x int, y int) bool {
    // TODO: 可以一次计算出R和U的数量
    steps := x + y
    rNum := strings.Count(command, "R") * (steps/len(command)) + strings.Count(command[:steps%len(command)], "R")
    uNum := strings.Count(command, "U") * (steps/len(command)) + strings.Count(command[:steps%len(command)], "U")
    if rNum == x && uNum == y {
        return true
    }
    return false
}

时间复杂度: O ( l e n ( c o m m a n d ) ∗ l e n ( o b s t a c l e s ) ) O(len(command) * len(obstacles)) O(len(command)len(obstacles))

x + y = K * len(command) 1 <= k <= 无穷大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值