Skip to content

Commit 88b1fff

Browse files
author
王鹏
committed
feat(MEDIUM): add LCP_3_robot
1 parent 3b4fb64 commit 88b1fff

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed

src/pp/arithmetic/LCP/_3_robot.java

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package pp.arithmetic.LCP;
2+
3+
import java.util.HashMap;
4+
import java.util.HashSet;
5+
import java.util.Map;
6+
import java.util.Set;
7+
8+
/**
9+
* Created by wangpeng on 2019-10-09.
10+
* LCP 3. 机器人大冒险
11+
* <p>
12+
* 力扣团队买了一个可编程机器人,机器人初始位置在原点(0, 0)。小伙伴事先给机器人输入一串指令command,机器人就会无限循环这条指令的步骤进行移动。指令有两种:
13+
* <p>
14+
* U: 向y轴正方向移动一格
15+
* R: 向x轴正方向移动一格。
16+
* 不幸的是,在 xy 平面上还有一些障碍物,他们的坐标用obstacles表示。机器人一旦碰到障碍物就会被损毁。
17+
* <p>
18+
* 给定终点坐标(x, y),返回机器人能否完好地到达终点。如果能,返回true;否则返回false。
19+
* <p>
20+
*  
21+
* <p>
22+
* 示例 1:
23+
* <p>
24+
* 输入:command = "URR", obstacles = [], x = 3, y = 2
25+
* 输出:true
26+
* 解释:U(0, 1) -> R(1, 1) -> R(2, 1) -> U(2, 2) -> R(3, 2)。
27+
* 示例 2:
28+
* <p>
29+
* 输入:command = "URR", obstacles = [[2, 2]], x = 3, y = 2
30+
* 输出:false
31+
* 解释:机器人在到达终点前会碰到(2, 2)的障碍物。
32+
* 示例 3:
33+
* <p>
34+
* 输入:command = "URR", obstacles = [[4, 2]], x = 3, y = 2
35+
* 输出:true
36+
* 解释:到达终点后,再碰到障碍物也不影响返回结果。
37+
*  
38+
* <p>
39+
* 限制:
40+
* <p>
41+
* 2 <= command的长度 <= 1000
42+
* command由U,R构成,且至少有一个U,至少有一个R
43+
* 0 <= x <= 1e9, 0 <= y <= 1e9
44+
* 0 <= obstacles的长度 <= 1000
45+
* obstacles[i]不为原点或者终点
46+
* <p>
47+
* 来源:力扣(LeetCode)
48+
* 链接:https://leetcode-cn.com/problems/programmable-robot
49+
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
50+
*/
51+
public class _3_robot {
52+
53+
public static void main(String[] args) {
54+
_3_robot robot = new _3_robot();
55+
System.out.println(robot.robot("URR", new int[][]{}, 3, 2));
56+
System.out.println(robot.robot("URR", new int[][]{{2, 2}}, 3, 2));
57+
System.out.println(robot.robot("URR", new int[][]{{4, 2}}, 3, 2));
58+
System.out.println(robot.robot("URRURRR", new int[][]{{7, 7}, {0, 5}, {2, 7}, {8, 6}, {8, 7}, {6, 5}, {4, 4}, {0, 3}, {3, 6}}, 4915, 1966));
59+
//优化解题
60+
System.out.println(robot.robot2("URR", new int[][]{}, 3, 2));
61+
System.out.println(robot.robot2("URR", new int[][]{{2, 2}}, 3, 2));
62+
System.out.println(robot.robot2("URR", new int[][]{{4, 2}}, 3, 2));
63+
System.out.println(robot.robot2("URRURRR", new int[][]{{7, 7}, {0, 5}, {2, 7}, {8, 6}, {8, 7}, {6, 5}, {4, 4}, {0, 3}, {3, 6}}, 4915, 1966));
64+
}
65+
66+
/**
67+
* 解题思路:
68+
* 简单直接能出结果,但是提交超时,主要耗时在障碍物的循环判断上,当障碍物太多了就比较耗时了
69+
* 比如这个case:https://leetcode-cn.com/submissions/detail/32424313/testcase/
70+
* <p>
71+
* 优化求解:{@link _3_robot#robot2(String, int[][], int, int)}
72+
*
73+
* @param command
74+
* @param obstacles
75+
* @param x
76+
* @param y
77+
* @return
78+
*/
79+
public boolean robot(String command, int[][] obstacles, int x, int y) {
80+
int index = 0;
81+
int length = command.length();
82+
int SX = 0, SY = 0;
83+
while (true) {
84+
char c = command.charAt(index % length);
85+
if (c == 'U') {
86+
SY++;
87+
} else if (c == 'R') {
88+
SX++;
89+
} else {
90+
break;
91+
}
92+
if (SX == x && SY == y) {
93+
return true;
94+
}
95+
//不考虑内存的话,可以考虑用map保存障碍物位置,本题提交不过x,y太大
96+
if (isInObstacles(SX, SY, obstacles) || SX > x || SY > y) {
97+
break;
98+
}
99+
index++;
100+
}
101+
102+
return false;
103+
}
104+
105+
private boolean isInObstacles(int x, int y, int[][] obstacles) {
106+
if (obstacles.length == 0) return false;
107+
for (int i = 0; i < obstacles.length; i++) {
108+
if (x == obstacles[i][0] && y == obstacles[i][1]) {
109+
return true;
110+
}
111+
}
112+
return false;
113+
}
114+
115+
/**
116+
* 解题思路:
117+
* 1、鉴于指令是不断走循环的,先算出一个循环内横向走的坐标xx和纵向走的坐标yy,后续的可以通过规则落到第一圈的坐标上
118+
* 2、利用map将一个循环走的坐标保存下来==>xx+"_"+yy,true
119+
* 3、计算走到目标坐标需要的循环次数,映射到第一圈中是否包含该坐标
120+
* 4、同理,循环障碍物,看映射到第一圈中是否包含该坐标
121+
*
122+
* 映射规则:x ==> x - circle * xx
123+
* <p>
124+
* 执行用时 : 3 ms, 在所有 Java 提交中击败了69.76%的用户
125+
* 内存消耗 :36 MB, 在所有 Java 提交中击败了100.00%的用户
126+
*
127+
* @param command
128+
* @param obstacles
129+
* @param x
130+
* @param y
131+
* @return
132+
*/
133+
public boolean robot2(String command, int[][] obstacles, int x, int y) {
134+
int xx = 0, yy = 0;
135+
Map<String, Boolean> set = new HashMap<>();
136+
set.put(xx + "_" + yy, true);
137+
//1
138+
for (char c : command.toCharArray()) {
139+
switch (c) {
140+
case 'U':
141+
yy++;
142+
break;
143+
case 'R':
144+
xx++;
145+
break;
146+
}
147+
//2
148+
set.put(xx + "_" + yy, true);
149+
}
150+
//3
151+
int circle = Math.min(x / xx, y / yy);
152+
if (!set.getOrDefault((x - circle * xx) + "_" + (y - circle * yy), false)) return false;
153+
154+
//4
155+
for (int[] item : obstacles) {
156+
if (item.length < 2) continue;
157+
if (item[0] > x || item[1] > y) continue;
158+
circle = Math.min(item[0] / xx, item[1] / yy);
159+
if (set.getOrDefault((item[0] - circle * xx) + "_" + (item[1] - circle * yy), false)) return false;
160+
}
161+
162+
return true;
163+
}
164+
165+
}

0 commit comments

Comments
 (0)