一、Problem
在無限的平面上,機器人最初位於 (0, 0) 處,面朝北方。機器人可以接受下列三條指令之一:
“G”:直走 1 個單位
“L”:左轉 90 度
“R”:右轉 90 度
機器人按順序執行指令 instructions,並一直重複它們。
只有在平面中存在環使得機器人永遠無法離開時,返回 true。否則,返回 false。
輸入:"GGLLGG"
輸出:true
解釋:
機器人從 (0,0) 移動到 (0,2),轉 180 度,然後回到 (0,0)。
重複這些指令,機器人將保持在以原點爲中心,2 爲半徑的環中進行移動。
提示:
1 <= instructions.length <= 100
instructions[i] 在 {‘G’, ‘L’, ‘R’} 中
二、Solution
方法一:模擬
一開始的錯誤思路:用 set 存儲每個座標點的字符串,如果再次遇到那麼證明有環,這是片面的,因爲我們可能一直重複該指令,比如下面的這種情況:
"GL"
輸出:false
預期:true
討論一下什麼情況會回到起點;
- 第一:從
(0, 0) -> (x, x) -> ... -> (0, 0)
,這個很好想 - 第二:排除第一種情況後(注是排除),執行完一遍指令 instructions 後,只要方向與初始方向不同,那麼執行 n 次指令機器人也不可能回到原點,因爲它的運動範圍只會不斷地向外擴張
class Solution {
final static int U = 0, D = 1, L = 2, R = 3;
public boolean isRobotBounded(String instructions) {
char s[] = instructions.toCharArray();
int x = 0, y = 0, d = U;
for (char c : s) {
if (c == 'G') {
switch (d) {
case U: x--; break;
case D: x++; break;
case L: y--; break;
case R: y++; break;
}
} else if (c == 'L') {
switch (d) {
case U: d = L; break;
case D: d = R; break;
case L: d = D; break;
case R: d = U; break;
}
} else { // else if (c == 'R')
switch (d) {
case U: d = R; break;
case D: d = L; break;
case L: d = U; break;
case R: d = D; break;
}
}
}
return (x == 0 && y == 0) || d != U;
}
}
這個代碼比較冗餘,方向之間的轉移可以通過數字變化來進行轉移,比如 1>2, 2->3, 3->4, 4->1,而 4->1 可以通過取模來實現
注:方向數組內部的一維數組的順序是根據你的取模邏輯取定義的,如果當前方向是向北(k = 0),那麼遇到向左轉,此時你的方向數組的 k+1 位置應該是向西 (0, -1)
class Solution {
final static int[][] dir = { {1,0},{0,-1},{-1,0},{0,1} }; //北、西、
public boolean isRobotBounded(String instructions) {
char s[] = instructions.toCharArray();
int x = 0, y = 0, k = 0;
for (char c : s) {
if (c == 'L') {
k = (k + 1) % 4;
} else if (c == 'R'){
k = (k + 3) % 4;
} else {
x += dir[k][0];
y += dir[k][1];
}
}
return (x == 0 && y == 0) || k != 0;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,