No.3 Find theCity With theSmallest Number of Neighbors at a Threshold Distance
解题思路
这道题目需要求出任意两个城市之间的最短路径, 所以使用 floyd 算法.
时间复杂度:o(n^3), 而 n <= 100, 可以通过.
空间复杂度:o(n^2).
代码展示
class Solution {
public int findTheCity(int n, int[][] edges, int distanceThreshold) {
final int INF = 0x3f3f3f3f; // 不使用 Integer.MAX_VALUE, 避免加法溢出
int[][] dis = new int[n][n]; // dis[i][j] 表示 i 和 j 之间的最短路长度
// 初始化为无穷大
for (int i = 0; i < n; i++) {
Arrays.fill(dis[i], INF);
}
// 使用直接相连的边计算一部分 dis
for (int[] edge : edges) {
dis[edge[0]][edge[1]] = Math.min(edge[2], dis[edge[0]][edge[1]]);
dis[edge[1]][edge[0]] = Math.min(edge[2], dis[edge[1]][edge[0]]);
}
// floyd 算法三层循环, 求出所有的 dis
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dis[i][j] = Math.min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
// 根据 dis 统计每个城市可以在 distanceThreshold 内到达的城市数量, 得到答案
int city = -1, counter = INF;
for (int i = 0; i < n; i++) {
int cnt = 0;
for (int j = 0; j < n; j++) {
cnt += dis[i][j] <= distanceThreshold && i != j ? 1 : 0;
}
if (cnt <= counter) {
city = i;
counter = cnt;
}
}
return city;
}
}
No.4 Minium Difficulty of a Job Schedule
解题思路
动态规划问题.
定义状态: f[i][j] 表示前 i 天完成前 j 项任务的最小难度和
状态转移方程: f[i][j] = min{ f[i-1][k] + maxDifficulty(k + 1, j) }, 其中第 i 天完成的任务就是第 k + 1 项到第 j 项, 枚举 k.
初始状态: f[0][0] = 0, 其他均为 INF
最终答案: f[d][n] 即 d 天完成全部 n 项任务的最小难度和
非法情况: 即无法完成任务的情况. 在 n < d 时无法做到每天至少完成一项任务, 此时应该返回 -1
时间复杂度: o(n^3) = 状态数量 o(n^2) *times 状态转移时间\ o(n)
空间复杂度: o(n^2)
优化: 动态规划可以使用滚动数组将空间优化到 o(n), 并且 maxd 数组可以使用 ST 表优化到 $o(nlogn)$ 的时空复杂度. 但是由于动态规划仍然要花费 o(n^3) 的时间, 所以使用 ST 表并不能显著优化整体运行时间.
代码展示
class Solution {
public int minDifficulty(int[] jobDifficulty, int d) {
if (jobDifficulty == null || jobDifficulty.length < d) {
return -1;
}
final int INF = 0x3f3f3f3f;
int n = jobDifficulty.length;
int[][] f = new int[d + 1][n + 1];
int[][] maxd = new int[n][n];
// 初始化 f
for (int i = 0; i <= d; i++) {
Arrays.fill(f[i], INF);
}
f[0][0] = 0;
// 预处理 maxd 数组
for (int i = 0; i < n; i++) {
maxd[i][i] = jobDifficulty[i];
}
for (int i = 1; i < n; i++) {
for (int j = 0; j + i < n; j++) {
maxd[j][j + i] = Math.max(maxd[j][j + i - 1], jobDifficulty[j + i]);
}
}
// 动态规划递推
for (int i = 1; i <= d; i++) {
for (int j = i; j <= n; j++) {
for (int k = i - 1; k < j; k++) {
f[i][j] = Math.min(f[i][j], f[i - 1][k] + maxd[k][j - 1]); // f: 1-indexed maxd: 0-indexed
}
}
}
return f[d][n];
}
}
今天一定要努力刷题
绝对不会浪费时间
想要了解最新的最新的周赛题解信息,可以入群与大佬们交流~
