一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して14日目です。クリックしてイベントの詳細をご覧ください。
トピックの説明
これは2069年です。LeetCodeでの歩行ロボットIIのシミュレーション、中程度の。
タグ:「シミュレーション」、「頭の体操」
XY
平面 上のグリッド図を提供します。width x height
左下隅のグリッドは
、右上のグリッドは
。グリッドマップ内の隣接するセルは、4つの基本的な方向(、、、"North"
および ) "East"
にます。ロボットがグリッドから始まります "South"
"West"
、方向は "East"
。
ロボットは、コマンドに従って指定されたステップ数を移動できます。各ステップで、次のアクションを実行できます。
- 現在の方向に一歩前進してみてください。
- ロボットが到達する次の正方形が範囲外の場合、ロボットは再び前進しようとする前に反時計回りに90度回転します。
ロボットがコマンドに必要な数の移動を完了すると、ロボットは移動を停止し、次のコマンドを待ちます。
Robot
クラスを実装してください :
Robot(int width, int height)
width x height
グリッドマップを 初期化し ます。ロボットは最初に ,方向朝"East"
。void move(int num)
ロボットにnum
前進ます。int[] getPos()
の長さを使用して、ロボットの現在のグリッド位置を返します の配列 はを意味します。String getDir()
現在のロボットの向きを、、、 または"North"
として 返し ます。"East"
"South"
"West"
例1:
输入:
["Robot", "move", "move", "getPos", "getDir", "move", "move", "move", "getPos", "getDir"]
[[6, 3], [2], [2], [], [], [2], [1], [4], [], []]
输出:
[null, null, null, [4, 0], "East", null, null, null, [1, 2], "West"]
解释:
Robot robot = new Robot(6, 3); // 初始化网格图,机器人在 (0, 0) ,朝东。
robot.move(2); // 机器人朝东移动 2 步,到达 (2, 0) ,并朝东。
robot.move(2); // 机器人朝东移动 2 步,到达 (4, 0) ,并朝东。
robot.getPos(); // 返回 [4, 0]
robot.getDir(); // 返回 "East"
robot.move(2); // 朝东移动 1 步到达 (5, 0) ,并朝东。
// 下一步继续往东移动将出界,所以逆时针转变方向朝北。
// 然后,往北移动 1 步到达 (5, 1) ,并朝北。
robot.move(1); // 朝北移动 1 步到达 (5, 2) ,并朝 北 (不是朝西)。
robot.move(4); // 下一步继续往北移动将出界,所以逆时针转变方向朝西。
// 然后,移动 4 步到 (1, 2) ,并朝西。
robot.getPos(); // 返回 [1, 2]
robot.getDir(); // 返回 "West"
复制代码
ヒント:
move
,getPos
和getDir
总共调用次数不超过 次。
模拟
根据题目给定的移动规则可知,机器人总是在外圈移动(共上下左右四条),而移动方向分为四类:
当行走步数为
的整数倍时,会回到起始位置,因此我们可以通过维护一个变量 loc
来记录行走的总步数,并且每次将 loc
对 mod
进行取模来得到有效步数。
在回答 getPos
和 getDir
询问时,根据当前 loc
进行分情况讨论(见注释)。
另外还有一个小细节:根据题意,如果当前处于
位置,并且没有移动过,方向为 East
,若移动过,方向则为 South
,这可以通过一个变量 moved
来进行特判处理。
代码:
class Robot {
String[] ss = new String[]{"East", "North", "West", "South"};
int w, h, loc; // loc: 有效(取模后)移动步数
boolean moved; // 记录是否经过移动,用于特判 (0,0) 的方向
public Robot(int width, int height) {
w = width; h = height;
}
public void step(int num) {
moved = true;
loc += num;
loc %= 2 * (w - 1) + 2 * (h - 1);
}
public int[] getPos() {
int[] info = move();
return new int[]{info[0], info[1]};
}
public String getDir() {
int[] info = move();
int x = info[0], y = info[1], dir = info[2];
// 特殊处理当前在 (0,0) 的情况,当未移动过方向为 East,移动过方向为 South
if (x == 0 && y == 0) return moved ? ss[3] : ss[0];
return ss[dir];
}
int[] move() {
if (loc <= w - 1) {
// 当移动步数范围在 [0,w-1] 时,所在位置为外圈的下方,方向为 East
return new int[]{loc, 0, 0};
} else if (loc <= (w - 1) + (h - 1)) {
// 当移动步数范围在 [w,(w-1)+(h-1)] 时,所在位置为外圈的右方,方向为 North
return new int[]{w - 1, loc - (w - 1), 1};
} else if (loc <= 2 * (w - 1) + (h - 1)) {
// 当移动步数范围在 [(w-1)+(h-1)+1,2*(w-1)+(h-1)] 时,所在位置为外圈的上方,方向为 West
return new int[]{(w - 1) - (loc - ((w - 1) + (h - 1))), h - 1, 2};
} else {
// 当移动步数范围在 [2*(w-1)+(h-1)+1,2*(w-1)+2*(h-1)] 时,所在位置为外圈的左方,方向为 South
return new int[]{0, (h - 1) - (loc - (2 * (w - 1) + (h - 1))), 3};
}
}
}
复制代码
- 时间复杂度:
- 空间复杂度:
最后
これは、「BrushthroughLeetCode」シリーズの最初のNo.2169
記事シリーズは2021/01/01に始まります。開始日現在、LeetCodeには1916の質問があり、その一部はロックされています。最初にすべての質問を入力します。ロックなし。トピックは終了しました。
このシリーズの記事では、問題解決のアイデアを説明することに加えて、可能な限り最も簡潔なコードを示します。一般的なソリューションが含まれる場合は、対応するコードテンプレートも提供されます。
学生がコンピューター上でコードをデバッグして送信できるようにするために、関連するリポジトリgithub.com/SharingSour…を確立しました。
倉庫の住所には、一連の記事の解決策へのリンク、一連の記事の対応するコード、LeetCodeの元の質問へのリンクおよびその他の推奨される解決策が表示されます。