一、題目描述
力扣團隊買了一個可編程機器人,機器人初始位置在原點(0, 0)。小夥伴事先給機器人輸入一串指令 command,機器人就會無限循環這條指令的步驟進行移動。指令有兩種:
- U: 向 y 軸正方向移動一格
- R: 向 x 軸正方向移動一格。
不幸的是,在 xy 平面上還有一些障礙物,他們的座標用 obstacles 表示。機器人一旦碰到障礙物就會被損毀。
給定終點座標 (x, y),返回機器人能否完好地到達終點。如果能,返回 true;否則返回 false。
輸入:command = "URR", obstacles = [[2, 2]], x = 3, y = 2
輸出:false
解釋:機器人在到達終點前會碰到(2, 2)的障礙物。
二、題解
方法一:取次數
算法
- 先統計命令的移動方向的次數到
U
與R
中。 - 先判斷機器人是否遇到障礙物,後判斷是否能到達終點。
- 因爲終點 x 和 y 最大爲 ,所以枚舉所有點是不現實的。所以,我們採用取其循環次數,再利用乘法,判斷是否可達。
- 循環次數怎麼取?
- 毫無疑問是
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;
}
複雜度分析
- 時間複雜度:,
N
爲障礙物的個數。 - 空間複雜度:,