[LeetCode] Out of Boundary Paths 出界的路径
There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return it after mod 109 + 7.
Example 1:
Input:m = 2, n = 2, N = 2, i = 0, j = 0
Output: 6
Explanation:
Example 2:
Input:m = 1, n = 3, N = 3, i = 0, j = 1
Output: 12
Explanation:
Note:
- Once you move the ball out of boundary, you cannot move it back.
- The length and height of the grid is in range [1,50].
- N is in range [0,50].
这道题给了我们一个二维的数组,某个位置放个足球,每次可以在上下左右四个方向中任意移动一步,总共可以移动N步,问我们总共能有多少种移动方法能把足球移除边界,由于结果可能是个巨大的数,所以让我们对一个大数取余。那么我们知道对于这种结果很大的数如果用递归解法很容易爆栈,所以最好考虑使用DP来解。那么我们使用一个三维的DP数组,其中dp[k][i][j]表示总共走k步,从(i,j)位置走出边界的总路径数。那么我们来找递推式,对于dp[k][i][j],走k步出边界的总路径数等于其周围四个位置的走k-1步出边界的总路径数之和,如果周围某个位置已经出边界了,那么就直接加上1,否则就在dp数组中找出该值,这样整个更新下来,我们就能得出每一个位置走任意步数的出界路径数了,最后只要返回dp[N][i][j]就是所求结果了,参见代码如下:
解法一:
class Solution {
public:
int findPaths(int m, int n, int N, int i, int j) {
vector<vector<vector<int>>> dp(N + , vector<vector<int>>(m, vector<int>(n, )));
for (int k = ; k <= N; ++k) {
for (int x = ; x < m; ++x) {
for (int y = ; y < n; ++y) {
long long v1 = (x == ) ? : dp[k - ][x - ][y];
long long v2 = (x == m - ) ? : dp[k - ][x + ][y];
long long v3 = (y == ) ? : dp[k - ][x][y - ];
long long v4 = (y == n - ) ? : dp[k - ][x][y + ];
dp[k][x][y] = (v1 + v2 + v3 + v4) % ;
}
}
}
return dp[N][i][j];
}
};
下面这种方法虽然也是用的DP解法,但是DP数组的定义和上面的不一样,这种解法相当于使用了BFS搜索,以(i, j)为起始点,其中dp[k][x][y]表示用了k步,进入(x, y)位置的路径数,由于dp[k][x][y]只依赖于dp[k-1][x][y],所以我们可以用一个二维dp数组来代替,初始化dp[i][j]为1,总共N步,进行N次循环,每次都新建一个mxn大小的临时数组t,然后就是对于遍历到的每个位置,都遍历其四个相邻位置,如果相邻位置越界了,那么我们用当前位置的dp值更新结果res,因为此时dp值的意义就是从(i,j)到越界位置的路径数。如果没有,我们将当前位置的dp值赋给t数组的对应位置,这样在遍历完所有的位置时,将数组t整个赋值给dp,然后进入下一步的循环,参加代码如下:
解法二:
class Solution {
public:
int findPaths(int m, int n, int N, int i, int j) {
int res = ;
vector<vector<int>> dp(m, vector<int>(n, ));
dp[i][j] = ;
vector<vector<int>> dirs{{,-},{-,},{,},{,}};
for (int k = ; k < N; ++k) {
vector<vector<int>> t(m, vector<int>(n, ));
for (int r = ; r < m; ++r) {
for (int c = ; c < n; ++c) {
for (auto dir : dirs) {
int x = r + dir[], y = c + dir[];
if (x < || x >= m || y < || y >= n) {
res = (res + dp[r][c]) % ;
} else {
t[x][y] = (t[x][y] + dp[r][c]) % ;
}
}
}
}
dp = t;
}
return res;
}
};
参考资料:
https://discuss.leetcode.com/topic/88492/c-6-lines-dp-o-n-m-n-6-ms
https://discuss.leetcode.com/topic/88570/java-solution-dp-with-space-compression
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Out of Boundary Paths 出界的路径的更多相关文章
- LeetCode 257. Binary Tree Paths (二叉树路径)
Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...
- LeetCode OJ:Unique Paths(唯一路径)
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...
- leetcode 576. Out of Boundary Paths 、688. Knight Probability in Chessboard
576. Out of Boundary Paths 给你一个棋盘,并放一个东西在一个起始位置,上.下.左.右移动,移动n次,一共有多少种可能移出这个棋盘 https://www.cnblogs.co ...
- Python算法之动态规划(Dynamic Programming)解析:二维矩阵中的醉汉(魔改版leetcode出界的路径数)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_168 现在很多互联网企业学聪明了,知道应聘者有目的性的刷Leetcode原题,用来应付算法题面试,所以开始对这些题进行" ...
- Java实现 LeetCode 576 出界的路径数(DFS || DP)
576. 出界的路径数 给定一个 m × n 的网格和一个球.球的起始坐标为 (i,j) ,你可以将球移到相邻的单元格内,或者往上.下.左.右四个方向上移动使球穿过网格边界.但是,你最多可以移动 N ...
- BZOJ 1718: [Usaco2006 Jan] Redundant Paths 分离的路径( tarjan )
tarjan求边双连通分量, 然后就是一棵树了, 可以各种乱搞... ----------------------------------------------------------------- ...
- 【一天一道LeetCode】#63. Unique Paths II
一天一道LeetCode (一)题目 Follow up for "Unique Paths": Now consider if some obstacles are added ...
- 【LeetCode-面试算法经典-Java实现】【062-Unique Paths(唯一路径)】
[062-Unique Paths(唯一路径)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 A robot is located at the top-left c ...
- 【bzoj1718】Redundant Paths 分离的路径
1718: [Usaco2006 Jan] Redundant Paths 分离的路径 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 964 Solve ...
随机推荐
- Divisor counting [线性筛积性函数]
Divisor counting 题目大意:定义f(n)表示整数n的约数个数.给出正整数n,求f(1)+f(2)+...+f(n)的值. 注释:1<=n<=1000,000 想法:我们再次 ...
- 如何解决js递归里面出现的堆栈溢出
16.下面的递归代码在数组列表偏大的情况下会导致堆栈溢出.在保留递归模式的基础上,你怎么解决这个问题? var list = readHugeList(); var nextListItem = fu ...
- freemarker 类型转换
操作字符串函数 1. substring(start,end)从一个字符串中截取子串 start:截取子串开始的索引,start必须大于等于0,小于等于endend: 截取子串的长度,end必须大 ...
- NSURLSession http转Https
1.设置代理 NSURLSession *sesson = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defa ...
- Jquery点击除了指定div元素其他地方,隐藏该div
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script ty ...
- java程序在没有java环境的电脑上执行的方法(关键词jar,exe)
可以让你写的java程序在别人没有任何java配置以及环境的情况下执行 写好程序 在程序对应的package上右键->export->java->Runnable JAR file- ...
- beta冲刺6
前言:此篇是补昨天凌晨的.后面有更新但是太晚了就没有即使更新.所以现在过来更新一下. 昨天的未完成: 用户测试+测试报告 目前剩下的功能点:输入内容检测 我的社团输出显示格式调整. 今天的完成: 我的 ...
- Scala Option类型
转载自: Scala 初学者指南, 这里有一系列很棒的文章 类型 Option 可能你已经见过它在 Map API 中的使用:在实现自己的提取器时,我们也用过它, 然而,它还需要更多的解释. 你可能会 ...
- python之路--day6---文件处理
一.文件 1.文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件, 可以将自己的数据永久保存下来. 2.操作流程 #1. 打开文件,得到文件句柄并赋值给一个变量--f = o ...
- STM32F4系列单片机上使用CUBE配置MBEDTLS实现pem格式公钥导入
|版权声明:本文为博主原创文章,未经博主允许不得转载. 最近尝试在STM32F4下用MBEDTLS实现了公钥导入(我使用的是ECC加密),整个过程使用起来比较简单. 首先,STM32F4系列CUBE里 ...