有LeetCode算法/华为OD考试扣扣交流群可加 948025485
可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳od1441
了解算法冲刺训练(备注【CSDN】否则不通过)
从2024年4月15号开始,OD机考全部配置为2024D卷。
注意两个关键点:
- 会遇到C卷复用题。虽然可能存在幸存者偏差,但肯定还会有一大部分的旧题。
- 现在又支持做完题目之后倒回去改了。就是可以先做200的再做100的,然后可以反复提交。
题目描述与示例
题目描述
园区某部门举办了Family Day,邀请员工及其家属参加;将公司园区视为一个矩形,起始园区设置在左上角,终点园区设置在右下角;家属参观园区时,只能向右和向下园区前进;求从起始园区到终点园区会有多少条不同的参观路径
输入描述
第一行为园区长和宽;后面每一行表示该园区是否可以参观,0
表示可以参观,1
表示不能参观
1 <= 园区长, 园区宽 <= 100
输出描述
输出为不同的路径数量
示例
输入
3 3
0 0 0
0 1 0
0 0 0
输出
2
解题思路
注意,本题和LC63. 不同路径 II 完全一致,属于经典的二维dp路径问题。
代码
python
# 题目:【DP】2023C-园区参观路径
# 分值:200
# 作者:许老师-闭着眼睛学数理化
# 算法:DP
# 代码看不懂的地方,请直接在群上提问
# 输入长n、宽m
n, m = map(int, input().split())
# 构建网格
grid = list()
for _ in range(n):
row = list(map(int, input().split()))
grid.append(row)
# 设置二维数组 dp 用来储存到达每个位置时不同路径的数量
# dp[0][0] 表示从第 0 行第 0 列到达第 0 行第 0 列时不同路径的数量
# dp[0][i] 表示从第 0 行第 0 列到达第 0 行第 i 列时不同路径的数量
# dp[j][0] 表示从第 0 行第 0 列到达第 j 行第 0 列时不同路径的数量
# dp[i][j] 表示从第 0 行第 0 列到达第 i 行第 j 列时不同路径的数量
dp = [[0] * m for _ in range(n)]
# 初始化第一列的情况
for i in range(n):
# 如果遇到障碍,则退出循环
if grid[i][0] == 1:
break
# 否则记录到达点(i,0)的方法数为1种
dp[i][0] = 1
# 初始化第一行的情况
for j in range(m):
# 如果遇到障碍,则退出循环
if grid[0][j] == 1:
break
# 否则记录到达点(0,j)的方法数为1种
dp[0][j] = 1
# 双重循环执行dp过程
for i in range(1, n):
for j in range(1, m):
# 如果点(i,j)是障碍,则跳过
if grid[i][j] == 1:
continue
# 否则,点(i,j)既可以从左边(i,j-1)也可以从上边(i-1,j)转移过来
dp[i][j] = dp[i][j-1] + dp[i-1][j]
# 输出dp数组到达点(n-1,m-1)的方法数,即为达到右下角的方法数
print(dp[n-1][m-1])
java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
scanner.nextLine(); // Consume the rest of the line
int[][] grid = new int[n][m];
int[][] dp = new int[n][m];
for (int i = 0; i < n; ++i) {
String[] row = scanner.nextLine().split(" ");
for (int j = 0; j < m; ++j) {
grid[i][j] = Integer.parseInt(row[j]);
}
}
for (int i = 0; i < n; ++i) {
if (grid[i][0] == 1) break;
dp[i][0] = 1;
}
for (int j = 0; j < m; ++j) {
if (grid[0][j] == 1) break;
dp[0][j] = 1;
}
for (int i = 1; i < n; ++i) {
for (int j = 1; j < m; ++j) {
if (grid[i][j] == 1) continue;
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
System.out.println(dp[n-1][m-1]);
scanner.close();
}
}
cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> grid(n, vector<int>(m));
vector<vector<int>> dp(n, vector<int>(m, 0));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> grid[i][j];
}
}
for (int i = 0; i < n; ++i) {
if (grid[i][0] == 1) break;
dp[i][0] = 1;
}
for (int j = 0; j < m; ++j) {
if (grid[0][j] == 1) break;
dp[0][j] = 1;
}
for (int i = 1; i < n; ++i) {
for (int j = 1; j < m; ++j) {
if (grid[i][j] == 1) continue;
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
cout << dp[n-1][m-1] << endl;
return 0;
}
时空复杂度
时间复杂度:O(NM)
。dp过程中,双重循环所需时间复杂度
空间复杂度:O(NM)
。二维dp数组所占空间。
华为OD算法/大厂面试高频题算法练习冲刺训练
-
华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务300+同学成功上岸!
-
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
-
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
-
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
-
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
-
可查看链接 大厂真题汇总 & OD真题汇总(持续更新)
-
绿色聊天软件戳
od1336
了解更多