【數論】B043_機器人大冒險(取次數)

一、題目描述

力扣團隊買了一個可編程機器人,機器人初始位置在原點(0, 0)。小夥伴事先給機器人輸入一串指令 command,機器人就會無限循環這條指令的步驟進行移動。指令有兩種:

  • U: 向 y 軸正方向移動一格
  • R: 向 x 軸正方向移動一格。

不幸的是,在 xy 平面上還有一些障礙物,他們的座標用 obstacles 表示。機器人一旦碰到障礙物就會被損毀。

給定終點座標 (x, y),返回機器人能否完好地到達終點。如果能,返回 true;否則返回 false。

0<=x<=1e9,0<=y<=1e90 <= x <= 1e^9, 0 <= y <= 1e^9

輸入:command = "URR", obstacles = [[2, 2]], x = 3, y = 2
輸出:false
解釋:機器人在到達終點前會碰到(2, 2)的障礙物。

二、題解

方法一:取次數

算法

  • 先統計命令的移動方向的次數到 UR 中。
  • 先判斷機器人是否遇到障礙物,後判斷是否能到達終點。
  • 因爲終點 x 和 y 最大爲 10910^9,所以枚舉所有點是不現實的。所以,我們採用取其循環次數,再利用乘法,判斷是否可達。
  • 循環次數怎麼取?
    • 毫無疑問是 min(endX/R, endY/U),對於障礙物也是同理的。

* 邊界錯誤:在這句話中:while (k < N && (endX > 0 || endY > 0)) 不能把 || 改爲 && 因爲機器人的命令是未知的,一定要等命令執行完。

public boolean robot(String command, int[][] obs, int x, int y) {
    char[] comm = command.toCharArray();
    int N = comm.length;
    int U = 0, R = 0;
    for (char c : comm) {
        if (c == 'U')	U++;
        else			R++;
    }
    
    for (int[] ob : obs) {
        if (ob[0] > x || ob[1] > y)
            continue;
        int times = Math.min(ob[0]/R, ob[1]/U);
        int endX = ob[0] - times * R;
        int endY = ob[1] - times * U;
        int k = 0;
        while (k < N && (endX > 0 || endY > 0)) {	//注意:這裏是 ||,因爲要等機器人走完命令才能判斷
            if (comm[k] == 'U')	endY--;
            else 				endX--;
            k++;
        }
        if (endX == 0 && endY == 0) //如果障礙物可達,返回false
            return false;
    }
    // 類似的算法
    int times = Math.min(x/R, y/U);
    int endX = x - times*R;
    int endY = y - times*U;
    int k = 0;
    while (k < N && (endX > 0 || endY > 0)) {
        if (comm[k] == 'U')	endY--;
        else 				endX--;
        k++;
    }
    return endX == 0 && endY == 0;
}

複雜度分析

  • 時間複雜度:O(N)O(N)N 爲障礙物的個數。
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章