目录
地图分析(medium)
题目解析
1.题目链接:. - 力扣(LeetCode)
2.题目描述
讲解算法原理
解法:
算法思路:
01矩阵的变型题,直接⽤多源bfs解决即可。
编写代码
c++算法代码:
class Solution
{
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
public:
int maxDistance(vector<vector<int>>& grid)
{
int m = grid.size(), n = grid[0].size();
vector<vector<int>> dist(m, vector<int>(n, -1));
queue<pair<int, int>> q;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
if(grid[i][j])
{
dist[i][j] = 0;
q.push({i, j});
}
int ret = -1;
while(q.size())
{
auto [a, b] = q.front(); q.pop();
for(int i = 0; i < 4; i++)
{
int x = a + dx[i], y = b + dy[i];
if(x >= 0 && x < m && y >= 0 && y < n && dist[x][y] == -1)
{
dist[x][y] = dist[a][b] + 1;
q.push({x, y});
ret = max(ret, dist[x][y]);
}
}
}
return ret;
}
};
java算法代码:
class Solution
{
int[] dx = {0, 0, 1, -1};
int[] dy = {1, -1, 0, 0};
public int maxDistance(int[][] grid)
{
int m = grid.length, n = grid[0].length;
int[][] dist = new int[m][n];
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
dist[i][j] = -1;
Queue<int[]> q = new LinkedList<>();
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
if(grid[i][j] == 1)
{
dist[i][j] = 0;
q.add(new int[]{i, j});
}
int ret = -1;
while(!q.isEmpty())
{
int[] t = q.poll();
int a = t[0], b = t[1];
for(int i = 0; i < 4; i++)
{
int x = a + dx[i], y = b + dy[i];
if(x >= 0 && x < m && y >= 0 && y < n && dist[x][y] == -1)
{
dist[x][y] = dist[a][b] + 1;
q.add(new int[]{x, y});
ret = Math.max(ret, dist[x][y]);
}
}
}
return ret;
}
}
课程表(medium)
题目解析
1.题目链接:. - 力扣(LeetCode)
2.题目描述
讲解算法原理
解法:
算法思路:
原问题可以转换成⼀个拓扑排序问题。
⽤BFS解决拓扑排序即可。
拓扑排序流程:
a. 将所有⼊度为0的点加⼊到队列中;
b. 当队列不空的时候,⼀直循环:
i. 取出队头元素;
ii. 将于队头元素相连的顶点的⼊度-1;
iii. 然后判断是否减成0,。如果减成0,就加⼊到队列中。
编写代码
c++算法代码:
class Solution
{
public:
bool canFinish(int n, vector<vector<int>>& p)
{
unordered_map<int, vector<int>> edges; // 邻接表 vector<int> in(n); // 存储每⼀个结点的⼊度
// 1. 建图
for(auto& e : p)
{
int a = e[0], b = e[1];
edges[b].push_back(a);
in[a]++;
}
// 2. 拓扑排序 - bfs
queue<int> q;
// 把所有⼊度为 0 的点加⼊到队列中
for(int i = 0; i < n; i++)
{
if(in[i] == 0) q.push(i);
}
// 层序遍历
while(!q.empty())
{
int t = q.front();
q.pop();
// 修改相连的边
for(int e : edges[t])
{
in[e]--;
if(in[e] == 0) q.push(e);
}
}
// 3. 判断是否有环
for(int i : in)
if(i)
return false;
return true;
}
};
java算法代码:
class Solution
{
public boolean canFinish(int n, int[][] p)
{
// 1. 准备⼯作
int[] in = new int[n]; // 统计每⼀个顶点的⼊度
Map<Integer, List<Integer>> edges = new HashMap<>(); // 邻接表存图 // 2. 建图
for(int i = 0; i < p.length; i++)
{
int a = p[i][0], b = p[i][1]; // b -> a
if(!edges.containsKey(b))
{
edges.put(b, new ArrayList<>());
}
edges.get(b).add(a);
in[a]++;
}
// 3. 拓扑排序
Queue<Integer> q = new LinkedList<>();
// (1) 先把⼊度为 0 的点,加⼊到队列中
for(int i = 0; i < n; i++)
{
if(in[i] == 0) q.add(i);
}
// (2) bfs
while(!q.isEmpty())
{
int t = q.poll();
for(int a : edges.getOrDefault(t, new ArrayList<>()))
{
in[a]--;
if(in[a] == 0) q.add(a);
}
}
// 4. 判断是否有环
for(int x : in)
if(x != 0) return false;
return true;
}
}