我们可以自行规定,每当我们进入一个新的节点:
- 先turnLeft()遍历当前方向的节点
- 之后每次turnRight(),重复四次,保证我们遍历所有方向的子节点(这里要四次是因为起始节点需要遍历四个方向,非其实节点只需要遍历非入射方向)
- 最后turnLeft(),面向入射节点
注意第二步当中,有两种情况,如果当前方向子节点是wall,我们直接turnRight(),否则我们只从子节点回来,是和当初入射的方向相反,所以这个时候我们需要turnLeft()来保证我们下一次访问的是原入射方向右边的子节点。
时间复杂度O(V + E),做法的话递推课循环都可以,我们两个解法都给出,对图的dfs循环实现不清楚的话,可以参考这篇文章。
递归:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* // This is the robot's control interface. | |
* // You should not implement it, or speculate about its implementation | |
* class Robot { | |
* public: | |
* // Returns true if the cell in front is open and robot moves into the cell. | |
* // Returns false if the cell in front is blocked and robot stays in the current cell. | |
* bool move(); | |
* | |
* // Robot will stay in the same cell after calling turnLeft/turnRight. | |
* // Each turn will be 90 degrees. | |
* void turnLeft(); | |
* void turnRight(); | |
* | |
* // Clean the current cell. | |
* void clean(); | |
* }; | |
*/ | |
class Solution { | |
public: | |
void cleanRoom(Robot& robot) { | |
dfs(robot); | |
} | |
private: | |
vector<pair<int, int>> dirs = { {1, 0}, {0, -1}, {-1, 0}, {0, 1} }; | |
unordered_set<string> visited; | |
int x = 0, y = 0, d = 0; | |
void dfs(Robot& robot) | |
{ | |
if (visited.count(to_string(x) + ":" + to_string(y))) | |
{ | |
//go back to previous point | |
turnRight(robot); | |
turnRight(robot); | |
return; | |
} | |
robot.clean(); | |
visited.insert(to_string(x) + ":" + to_string(y)); | |
turnLeft(robot); | |
for (int i = 0; i < 4; ++i) | |
{ | |
if (!moveForward(robot)) | |
{ | |
turnRight(robot); | |
continue; | |
} | |
dfs(robot); | |
//return back to previous location | |
moveForward(robot); | |
//when it comes back from dfs point | |
//it will be opposite direction to | |
//the direction when we goes in | |
turnLeft(robot); | |
} | |
//change the direction so we are facing | |
//going in point | |
turnLeft(robot); | |
} | |
void turnLeft(Robot& robot) | |
{ | |
robot.turnLeft(); | |
d = (d + 3) % 4; | |
} | |
void turnRight(Robot& robot) | |
{ | |
robot.turnRight(); | |
d = (d + 1) % 4; | |
} | |
bool moveForward(Robot& robot) | |
{ | |
bool canReach = robot.move(); | |
if (canReach) | |
{ | |
x += dirs[d].first; | |
y += dirs[d].second; | |
} | |
return canReach; | |
} | |
}; |
循环:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* // This is the robot's control interface. | |
* // You should not implement it, or speculate about its implementation | |
* class Robot { | |
* public: | |
* // Returns true if the cell in front is open and robot moves into the cell. | |
* // Returns false if the cell in front is blocked and robot stays in the current cell. | |
* bool move(); | |
* | |
* // Robot will stay in the same cell after calling turnLeft/turnRight. | |
* // Each turn will be 90 degrees. | |
* void turnLeft(); | |
* void turnRight(); | |
* | |
* // Clean the current cell. | |
* void clean(); | |
* }; | |
*/ | |
class Solution { | |
public: | |
void cleanRoom(Robot& robot) { | |
stack<int> st; | |
st.push(0); | |
clean(robot); | |
while(st.size()) | |
{ | |
int key = st.top(); | |
if(key < 4) | |
{ | |
if(!key)turnLeft(robot); | |
st.pop(); | |
st.push(key + 1); | |
if(moveForward(robot)){clean(robot);st.push(0);continue;} | |
turnRight(robot); | |
continue; | |
} | |
turnLeft(robot); | |
robot.move(); | |
x += dirs[d].first; | |
y += dirs[d].second; | |
st.pop(); | |
turnLeft(robot); | |
} | |
} | |
private: | |
vector<pair<int, int>> dirs = { {1, 0}, {0, -1}, {-1, 0}, {0, 1} }; | |
unordered_set<string> visited; | |
int x = 0, y = 0, d = 0; | |
void clean(Robot& robot) | |
{ | |
visited.insert(to_string(x) + ":" + to_string(y)); | |
robot.clean(); | |
} | |
void turnLeft(Robot& robot) | |
{ | |
robot.turnLeft(); | |
d = (d + 3) % 4; | |
} | |
void turnRight(Robot& robot) | |
{ | |
robot.turnRight(); | |
d = (d + 1) % 4; | |
} | |
bool moveForward(Robot& robot) | |
{ | |
bool canReach = robot.move(); | |
if (canReach) | |
{ | |
x += dirs[d].first; | |
y += dirs[d].second; | |
if(visited.count(to_string(x) + ":" + to_string(y))) | |
{ | |
x -= dirs[d].first; | |
y -= dirs[d].second; | |
canReach = false; | |
turnRight(robot); | |
turnRight(robot); | |
robot.move(); | |
turnRight(robot); | |
turnRight(robot); | |
} | |
} | |
return canReach; | |
} | |
}; |
No comments:
Post a Comment