There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolling up(u), down (d), left (l) or right (r), but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction. There is also a hole in this maze. The ball will drop into the hole if it rolls on to the hole.

Given the ball position, the hole position and the maze, find out how the ball could drop into the hole by moving the shortest distance. The distance is defined by the number of empty spaces traveled by the ball from the start position (excluded) to the hole (included). Output the moving directions by using 'u', 'd', 'l' and 'r'. Since there could be several different shortest ways, you should output the lexicographically smallest way. If the ball cannot reach the hole, output "impossible".

The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The ball and the hole coordinates are represented by row and column indexes.

Example 1:

Input 1: a maze represented by a 2D array

0 0 0 0 0
1 1 0 0 1
0 0 0 0 0
0 1 0 0 1
0 1 0 0 0 Input 2: ball coordinate (rowBall, colBall) = (4, 3)
Input 3: hole coordinate (rowHole, colHole) = (0, 1) Output: "lul" Explanation: There are two shortest ways for the ball to drop into the hole.
The first way is left -> up -> left, represented by "lul".
The second way is up -> left, represented by 'ul'.
Both ways have shortest distance 6, but the first way is lexicographically smaller because 'l' < 'u'. So the output is "lul".

Example 2:

Input 1: a maze represented by a 2D array

0 0 0 0 0
1 1 0 0 1
0 0 0 0 0
0 1 0 0 1
0 1 0 0 0 Input 2: ball coordinate (rowBall, colBall) = (4, 3)
Input 3: hole coordinate (rowHole, colHole) = (3, 0) Output: "impossible" Explanation: The ball cannot reach the hole.

Note:

  1. There is only one ball and one hole in the maze.
  2. Both the ball and hole exist on an empty space, and they will not be at the same position initially.
  3. The given maze does not contain border (like the red rectangle in the example pictures), but you could assume the border of the maze are all walls.
  4. The maze contains at least 2 empty spaces, and the width and the height of the maze won't exceed 30.

这道题DEBUG,DE了半天,用了朴素的DFS,但还是超时在大case上了。果然已经超出了我的能力范围。

class Solution {
private:
int arr[][] = { { , },{ ,- },{ , },{ -, } };
vector<string> directions = { "r","l","d","u" };
public:
string findShortestWay(vector<vector<int>>& maze, vector<int>& ball, vector<int>& hole) {
vector<string> ret;
set<int> visited;
helper(maze, ball[], ball[], hole, ret, visited, "");
sort(ret.begin(), ret.end());
string tmpstr = "";
if (ret.empty()) return "impossible";
//for(auto str : ret)cout << str << endl;
for (int i = ; i < ret[].size(); i++) {
if (tmpstr.empty()) {
tmpstr += ret[][i];
}
else {
if (tmpstr.back() != ret[][i]) {
tmpstr += ret[][i];
}
}
}
return tmpstr;
}
void helper(vector<vector<int>>& maze, int x, int y, vector<int>& hole, vector<string>& ret, set<int>& visited, string path) {
int m = maze.size();
int n = maze[].size();
if (visited.count(x * n + y)) return;
if (!ret.empty() && path.size() > ret[].size()) return;
visited.insert(x*n + y);
for (int i = ; i<; i++) {
int dx = arr[i][];
int dy = arr[i][];
int tmpx, tmpy;
tmpx = x + dx;
tmpy = y + dy;
string tmppath = path;
while (tmpx < m && tmpx >= && tmpy<n && tmpy >= && maze[tmpx][tmpy] != ) {
tmppath += directions[i];
if (tmpx == hole[] && tmpy == hole[]) {
// cout << tmppath << endl;
if(ret.empty() || tmppath.size() < ret[].size()){
ret.clear();
ret.push_back(tmppath);
}
else if(tmppath.size() == ret[].size()){
ret.push_back(tmppath);
}
//ret.push_back(tmppath);
//visited.erase(x*n + y);
//return;
}
tmpx += dx; tmpy += dy;
}
tmpx -= dx; tmpy -= dy;
if (tmpx == x && tmpy == y) continue;
//cout << "tmp location " << tmpx << " and " << tmpy << endl;
//cout << path << endl;
helper(maze, tmpx, tmpy, hole, ret, visited, tmppath);
}
visited.erase(x*n + y);
}
};

下面是我的解法的改进版,调了两个小时...

核心在于初始化一个最大值数组,记录每一个小球能滞留的点,如果这个点的值被更新且小于当前的cost直接返回,因为之前经过这个点的时候,就已经是比现在小的cost,再搜索下去没有意义。

然后在找到终点之后,更新结果,AC的结果依旧惨不忍睹。

Runtime: 160 ms, faster than 8.20% of C++ online submissions for The Maze III.

class Solution {
private:
int arr[][] = { { , },{ ,- },{ , },{ -, } };
vector<string> directions = { "r","l","d","u" };
public:
string findShortestWay(vector<vector<int>>& maze, vector<int>& ball, vector<int>& hole) {
string ret = "";
vector<vector<int>> visited(maze.size(), vector<int>(maze[].size(), INT_MAX));
helper(maze, ball[], ball[], hole, ret, visited, "", );
if (ret.empty()) return "impossible";
return ret;
}
void helper(vector<vector<int>>& maze, int x, int y, vector<int>& hole, string& ret, vector<vector<int>>& visited, string path, int cost) {
int m = maze.size();
int n = maze[].size();
if (visited[x][y] >= cost) {
visited[x][y] = cost;
}
else {
return;
}
for (int i = ; i<; i++) {
int dx = arr[i][];
int dy = arr[i][];
int tmpx, tmpy, tmpcost = cost;
bool check = false, found = false, inloop = false;
tmpx = x;
tmpy = y;
string tmppath = path;
while (tmpx < m && tmpx >= && tmpy<n && tmpy >= && maze[tmpx][tmpy] != ) {
if (!check) {
tmppath += directions[i];
check = true;
}
if (tmpx == hole[] && tmpy == hole[]) {
if (visited[tmpx][tmpy] > tmpcost) {
visited[tmpx][tmpy] = tmpcost;
ret = tmppath;
}
else if(visited[tmpx][tmpy] == tmpcost && ret > tmppath){
ret = tmppath;
}
found = true;
}
tmpx += dx; tmpy += dy;
tmpcost++;
inloop = true;
}
if (inloop) {
tmpx -= dx;
tmpy -= dy;
tmpcost--;
}
if (tmpx == x && tmpy == y) continue;
//if (found) continue;
//cout << "tmp location " << tmpx << " and " << tmpy << endl;
//cout << path << endl;
helper(maze, tmpx, tmpy, hole, ret, visited, tmppath, tmpcost);
}
}
};

下面是网上的解法,用的是BFD。要求图上某一个点到已知点距离最近的方法就是BFS。但我觉得能存在更好的办法(Dijkstra)。

Runtime: 4 ms, faster than 100.00% of C++ online submissions for The Maze III.

#include "header.h"
class Solution {
public:
vector<vector<int>> dir = { { ,, },{ ,, },{ -,, },{ ,-, } };
vector<string> ds = { "d", "r", "u", "l" };
//d, r, u, l
string findShortestWay(vector<vector<int>>& maze, vector<int>& ball, vector<int>& hole) {
//2018-12-18 解决了maze I and maze II,我觉得本质上还是BFS的问题,这个时候的destination只是说变成了如果掉进了hole,那么就不在运动了这样
//哈哈哈哈哈哈一次AC!赞!
if (maze.empty()) return "";
int m = maze.size();
int n = maze[].size();
vector<vector<pair<int, string> >> check(m, vector<pair<int, string> >(n, { INT_MAX, "" }));
check[ball[]][ball[]] = { , "" };
queue<pair<int, int>> q;
q.push({ ball[], ball[] });
while (!q.empty()) {
int len = q.size();
while (len) {
auto p = q.front(); q.pop(); len--;
for (auto d : dir) {
int steps = ;
int i = p.first; int j = p.second;
while (i + d[] >= && i + d[] < m && j + d[] >= && j + d[] < n && !maze[i + d[]][j + d[]]) {
i = i + d[]; j = j + d[]; steps++;
if (i == hole[] && j == hole[]) { break; }
}
if (check[i][j].first > check[p.first][p.second].first + steps) {
check[i][j].first = check[p.first][p.second].first + steps;
check[i][j].second = check[p.first][p.second].second + ds[d[]];
q.push({ i, j });
}
else if (check[i][j].first == check[p.first][p.second].first + steps) {
if (check[i][j].second > check[p.first][p.second].second + ds[d[]]) {
q.push({ i, j });
check[i][j].second = check[p.first][p.second].second + ds[d[]];
}
}
}
}
}
return check[hole[]][hole[]].first == INT_MAX ? "impossible" : check[hole[]][hole[]].second;
}
};

LC 499. The Maze III 【lock,hard】的更多相关文章

  1. LC 245. Shortest Word Distance III 【lock, medium】

    Given a list of words and two words word1 and word2, return the shortest distance between these two ...

  2. LC 759. Employee Free Time 【lock, hard】

    We are given a list schedule of employees, which represents the working time for each employee. Each ...

  3. Leetcode: The Maze III(Unsolved Lock Problem)

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  4. LeetCode 499. The Maze III

    原题链接在这里:https://leetcode.com/problems/the-maze-iii/ 题目: There is a ball in a maze with empty spaces ...

  5. [LeetCode] 499. The Maze III 迷宫 III

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  6. LC 871. Minimum Number of Refueling Stops 【lock, hard】

    A car travels from a starting position to a destination which is target miles east of the starting p ...

  7. LC 660. Remove 9 【lock, hard】

    Start from integer 1, remove any integer that contains 9 such as 9, 19, 29... So now, you will have ...

  8. LC 656. Coin Path 【lock, Hard】

    Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The ...

  9. LC 244. Shortest Word Distance II 【lock, Medium】

    Design a class which receives a list of words in the constructor, and implements a method that takes ...

随机推荐

  1. OWASP Hakcing Lab在线漏洞环境

    OWASP Hakcing Lab在线漏洞环境   OWASP hakcing-lab 是一个提供免费的远程安全(Web)挑战和 OWASP TOP 10,OWASP WebGoat,OWASP Ha ...

  2. opencv,用摄像头识别贴片元件的定位和元件的角度(转载)

    经过半个月学习opencv有点小成果,用摄像头识别贴片元件的定位和元件的角度(转载) (2013-04-17 16:00:22) 转载▼   分类: 学习笔记 先说一下开源的opencv真是一件伟大的 ...

  3. 版本控制工具 svn 一

    一.svn 概述 1).svn的作用 1.多人协作开发:2.远程控制:3.版本控制 2).软件控制管理工具发展之路 SCM:软件配置管理,所谓的软件配置管理实际就是软件源代码的 控制与管理. CVS: ...

  4. 解决remix在线编译器连接本地私有链环境不成功的问题

    一.部署合约到私有链环境 选择"environment"里的"Web3 Provider" 弹出RPC连接地址输入框 输入我们Geth客户端安装服务器的IP:9 ...

  5. CSS字体中英文名称对照表

    在CSS文件中,我们常看到有些字体名称变成了乱码,这是由于编写者将中文字体的名字直接写成了中文,并且再上传或者拷贝复制的时候无意间变成了乱码. 为了避免这种状况出现,在CSS文件中使用中文字体时,最好 ...

  6. dockerfile 与 docker-compose的区别

    https://blog.csdn.net/londa/article/details/91815208 先简单理解 docker 的使用过程,它分为镜像构建与容器启动. 镜像构建:即创建一个镜像,它 ...

  7. 为什么JAVA对象需要实现序列化?

    https://blog.csdn.net/yaomingyang/article/details/79321939 序列化是一种用来处理对象流的机制. 所谓对象流:就是将对象的内容进行流化.可以对流 ...

  8. 关于HTML5视频标签的问题

    一.基本 video标签在兼容性上还是比较差的,如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8的(Opera.Mozilla.Chrome),支持H.264的( ...

  9. maven 项目下 Maven Dependencies 下列表为空

    问题如题,如下图: 解决: 选中 Maven Dependencies ,右键 属性 如下图: 把   resolve dependencies from workspace projects   这 ...

  10. 运行别人的Vue项目

    步骤一:先 安装 cnpm cmd命令下 输入  npm install -g cnpm --registry=http://registry.npm.taobao.org (由于npm有些资源被屏蔽 ...