矩阵的最短通路值

矩阵的最短通路值

一、题目

用一个整形矩阵 matrix 表示一个网络,1 代表有路,0 代表无路,每一个位置只要不越界,都有上下左右 4 个方向,求从最左上角到最右下角的最短通路值

如下举例:

1
2
3
4
5
6
7
matrix = {
{1, 0, 1, 1, 1},
{1, 0, 1, 0, 1},
{1, 1, 1, 0, 1},
{0, 0, 0, 0, 1},
}
通路只有一条,由 12 个 1 构成,返回 12

二、思路

这道题目我们可以使用广度优先遍历这个矩阵。我们新创建一个矩阵 map 用来记录最短的通路值,用一个队列来记录广度搜索的坐标。

首先过滤哪些边界条件,即矩阵为空,矩阵的左上角元素不为 1 或者矩阵的右下角的元素不为 1。这些都直接返回 0。

队列中插入 (0, 0) 坐标。将 map[0][0] 赋为 1。然后循环取出队列中的坐标,如果此坐标已经是右下角的坐标了,直接返回即可。如果不是,则从此坐标的上下左右四个方向去遍历。并且给 矩阵 map 的对应坐标的元素加一。

再朝着坐标的四个方向去遍历时,要注意,原始矩阵 matrix 的坐标应该不为 0,为 0 说明不是通路。新矩阵 map 的坐标应该为 0,不为 0 说明已经遍历过,不用再去遍历了。因为是广度搜索,所以对于最短通路值而言,已经遍历过的元素不用再遍历。

三、代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <vector>
#include <queue>

void print_matrix(const std::vector<std::vector<int>>& matrix) {
for (const auto& arr : matrix) {
for (const auto& x : arr) {
std::cout << x << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}

class Solution {
public:
int get_min_path_value(const std::vector<std::vector<int>>& matrix) {
if (matrix.empty() || matrix[0][0] == 0
|| matrix[matrix.size()-1][matrix[0].size()-1] == 0) {
return 0;
}
int rows = matrix.size(), lines = matrix[0].size();
std::vector<std::vector<int>> mp(rows, std::vector<int>(lines, 0));
std::queue<std::pair<int, int>> qu;
qu.push({0, 0});
mp[0][0] = 1;
for (; !qu.empty();) {
auto& node = qu.front();
qu.pop();
int row = node.first, line = node.second;
if (row == rows-1 && line == lines-1) {
print_matrix(mp);
return mp[row][line];
}
go_walk(matrix, mp, mp[row][line], row-1, line, qu);
go_walk(matrix, mp, mp[row][line], row+1, line, qu);
go_walk(matrix, mp, mp[row][line], row, line-1, qu);
go_walk(matrix, mp, mp[row][line], row, line+1, qu);
print_matrix(mp);
}
return 0;
}

private:
void go_walk(
const std::vector<std::vector<int>>& matrix,
std::vector<std::vector<int>>& mp,
int pre,
int row, int line,
std::queue<std::pair<int, int>>& qu) {
if (row < 0 || line < 0 || row >= matrix.size() || line >= matrix[0].size()
|| matrix[row][line] == 0 || mp[row][line] != 0) {
return;
}
mp[row][line] = pre+1;
qu.push({row, line});
}
};

int main() {
std::vector<std::vector<int>> matrix{
{1, 0, 1, 1, 1},
{1, 0, 1, 0, 1},
{1, 1, 1, 0, 1},
{0, 0, 0, 0, 1},
};
Solution s;
auto res = s.get_min_path_value(matrix);
std::cout << res << std::endl;
return 0;
}

时间复杂度为:O(N),空间复杂度:O(N*M)