leetcode 1293. Shortest Path in a Grid with Obstacles Elimination | 1293. 网格中的最短路径(BFS)

本文主要是介绍leetcode 1293. Shortest Path in a Grid with Obstacles Elimination | 1293. 网格中的最短路径(BFS),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

https://leetcode.com/problems/shortest-path-in-a-grid-with-obstacles-elimination/
在这里插入图片描述

题解

DFS 递归超时,看了评论区 & 答案区,没有可运行的 DFS 解法,这题只能 BFS。疑问:DFS 的复杂度是多少?

尝试改成带缓存的递归,但是由于 visited 数组的存在,当前状态还与整个 visited 表有关,dfs(x, y, k) 三个参数不足以表示当前状态,无法加缓存,除非将 visited 数组也当做缓存的一个维度。

尝试用 dp[x][y][k] 剪枝优化,如果已经遇到过 dp[x][y][k],且之前的 k 大于当前的 k,则剪枝,此优化几乎无效果。

总结:带有visited数组的回溯是一种有后效性的递归,无法转换成dp.

BFS 参考:Java-Straightforward-BFS-O(MNK)-time-or-O(MNK)-space

方法1:DFS(TLE)

本地测过几个例子,代码应该没问题。

class Solution {int M;int N;public int shortestPath(int[][] grid, int k) {M = grid.length;N = grid[0].length;boolean[][] visited = new boolean[M][N];k = grid[0][0] == 1 ? k - 1 : k;int res = bfs(0, 0, 0, k, grid, visited);System.out.println(res);return res == Integer.MAX_VALUE ? -1 : res;}// at position (x,y), remain k obstacles to remove// if valid, return min stepspublic int bfs(int steps, int x, int y, int k, int[][] grid, boolean[][] visited) {if (x < 0 || x >= M || y < 0 || y >= N || visited[x][y] || k < 0) return Integer.MAX_VALUE;if (x == M - 1 && y == N - 1) return steps;int t = grid[x][y] == 0 ? k : k - 1;visited[x][y] = true;int p1 = bfs(steps + 1, x, y - 1, t, grid, visited);int p2 = bfs(steps + 1, x, y + 1, t, grid, visited);int p3 = bfs(steps + 1, x - 1, y, t, grid, visited);int p4 = bfs(steps + 1, x + 1, y, t, grid, visited);visited[x][y] = false;return Math.min(Math.min(p1, p2), Math.min(p3, p4));}
}
方法2:BFS(AC)
class Solution {int M;int N;int[][] ways = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};public int shortestPath(int[][] grid, int k) {M = grid.length;N = grid[0].length;Queue<int[]> queue = new LinkedList<>();boolean[][][] visited = new boolean[M][N][k + 1];visited[0][0][0] = true;queue.offer(new int[]{0, 0, 0});int step = 0;while (!queue.isEmpty()) {int size = queue.size();for (int i = 0; i < size; i++) {int[] record = queue.poll();int x = record[0];int y = record[1];int curK = record[2];if (x == M - 1 && y == N - 1) return step;for (int[] way : ways) { // 4个方向int nextX = x + way[0];int nextY = y + way[1];int nextK = curK;if (nextX >= 0 && nextX < M && nextY >= 0 && nextY < N) {if (grid[nextX][nextY] == 1) nextK++;if (nextK <= k && !visited[nextX][nextY][nextK]) {visited[nextX][nextY][nextK] = true;queue.offer(new int[]{nextX, nextY, nextK});}}}}step++;}return -1;}
}

在这里插入图片描述

这篇关于leetcode 1293. Shortest Path in a Grid with Obstacles Elimination | 1293. 网格中的最短路径(BFS)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/556958

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

hdu1254(嵌套bfs,两次bfs)

/*第一次做这种题感觉很有压力,思路还是有点混乱,总是wa,改了好多次才ac的思路:把箱子的移动当做第一层bfs,队列节点要用到当前箱子坐标(x,y),走的次数step,当前人的weizhi(man_x,man_y),要判断人能否将箱子推到某点时要嵌套第二层bfs(人的移动);代码如下:

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

poj 2195 bfs+有流量限制的最小费用流

题意: 给一张n * m(100 * 100)的图,图中” . " 代表空地, “ M ” 代表人, “ H ” 代表家。 现在,要你安排每个人从他所在的地方移动到家里,每移动一格的消耗是1,求最小的消耗。 人可以移动到家的那一格但是不进去。 解析: 先用bfs搞出每个M与每个H的距离。 然后就是网络流的建图过程了,先抽象出源点s和汇点t。 令源点与每个人相连,容量为1,费用为

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

POJ 3057 最大二分匹配+bfs + 二分

SampleInput35 5XXDXXX...XD...XX...DXXXXX5 12XXXXXXXXXXXXX..........DX.XXXXXXXXXXX..........XXXXXXXXXXXXX5 5XDXXXX.X.DXX.XXD.X.XXXXDXSampleOutput321impossible

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点