之前收藏了极客时间的算法训练营3期 共21课,计划每一课写博客来记录学习,主要形式为
方法类型1
题1
题解
题2
题解
方法类型2
题1
题解
……
题目大体来自leetcode 和 acwing
主要记录和理解代码,所以基本完全搬运了视频题解代码,
个人学习感受体现在大致思路的总结和注释上。
第一题
Bellmen -ford
最多n - 1轮,可以处理有负数边的情况
class Solution {
public:
int networkDelayTime(vector<vector<int>>& times, int n, int k) {
vector<int> dist(n + 1, 1e9);
dist[k] = 0;
for (int round = 1; round <= n - 1; round++) {
for (vector<int> time : times) {
int x = time[0];
int y = time[1];
int z = time[2];
if (dist[x] + z < dist[y])
dist[y] = dist[x] + z;
}
}
int ans = 0;
for (int i = 1; i <= n; i++) ans = max(ans, dist[i]);
return ans == 1e9 ? -1 : ans;
}
};
Dijkstra
正边权,O(n2)
class Solution {
public:
int networkDelayTime(vector<vector<int>>& times, int n, int k) {
vector<int> dist(n + 1, 1e9);
vector<vector<int>> to = vector<vector<int>>(n + 1, vector<int>());
vector<vector<int>> edge = vector<vector<int>>(n + 1, vector<int>());
for (vector<int> time : times) {
int x = time[0];
int y = time[1];
int z = time[2];
to[x].push_back(y);
edge[x].push_back(z);
}
vector<bool> expand(n + 1, false);
dist[k] = 0;
for (int round = 0; round < n; round++) {
int tmp = 1e9;
int x;
for (int i = 1; i <= n; i++) {
if (!expand[i] && dist[i] < tmp){
tmp = dist[i];
x = i;
}
}
expand[x] = true;
for (int i = 0; i < to[x].size(); i++) {
int y = to[x][i];
int z = edge[x][i];
if (dist[x] + z < dist[y]){
dist[y] = dist[x] + z;
}
}
}
int ans = 0;
for (int i = 1; i <= n; i++) ans = max(ans, dist[i]);
return ans == 1e9 ? -1 : ans;
}
};
第二题
floid 得到所有最短距离,再统计。
class Solution {
public:
int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {
vector<vector<int>> dist(n, vector<int>(n, 1e9));
for (int i = 0; i < n; i++) dist[i][i] = 0;
for (vector<int> edge : edges) {
int x = edge[0];
int y = edge[1];
int z = edge[2];
dist[x][y] = dist[y][x] = z;
}
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
int Minneighbour = 1e9;
int ans;
for (int i = 0; i < n; i++) {
int neighbour = 0;
for (int j = 0; j < n; j++) {
if (i != j && dist[i][j] <= distanceThreshold){
neighbour++;
}
}
if (neighbour <= Minneighbour) {
Minneighbour = neighbour;
ans = i;
}
}
return ans;
}
};
第三题
最朴素的Kruskal,,超时。
class Solution {
public:
int minCostConnectPoints(vector<vector<int>>& points) {
int n = points.size();
fa = vector<int>(n);
for (int i = 0; i < n; i++) fa[i] = i;
vector<vector<int>> edges;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++) {
edges.push_back({i, j, abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1])});
}
sort(edges.begin(), edges.end(), [](vector<int> A, vector<int> B){
return A[2] < B[2];
});
int ans = 0;
for (vector<int> edge : edges) {
int x = edge[0];
int y = edge[1];
int z = edge[2];
x = find(x);
y = find(y);
if (x != y) {
ans += z;
fa[x] = y;
}
}
return ans;
}
private:
vector<int> fa;
int find(int x) {
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
};