Problem: 2477. 到达首都的最少油耗
文章目录
- 思路
- 解题过程
- 复杂度
- Code
思路
为了解决这个问题,我们使用深度优先搜索(DFS)算法来遍历给定的树形结构。在这个过程中,我们维护两个数组,size 和 cost,分别用于记录每个节点的子节点数量和到达该节点的总成本。对于每个节点,我们递归地访问其所有子节点,计算它们的子节点总数以及到达这些子节点的总成本。在回溯时,我们更新当前节点的成本,将子节点的成本加上从子节点到当前节点的额外成本。额外成本由子节点的总人数除以座位数向上取整得到,这是因为每辆车最多能坐seats人。
解题过程
初始化一个邻接列表grip,用来存储图中每个节点的邻居。使用roads数组填充邻接列表,构建图。定义size和cost数组,其中size[i]表示节点i的子节点数,cost[i]表示到达节点i的总成本。调用递归函数f,以头节点0开始,计算整个图的子节点数和成本。最终返回cost[0]作为到达首都的最少油耗。
复杂度
- 时间复杂度: O ( n ) O(n) O(n),其中n是节点的数量。因为每个节点恰好被访问一次。
- 空间复杂度: O ( n ) O(n) O(n),主要来自于递归调用栈的深度,最坏情况下为树的高度,即n。
Code
class Solution {public static long minimumFuelCost(int[][] roads, int seats) {int n = roads.length + 1; // 节点的数量ArrayList<ArrayList<Integer>> grip = new ArrayList<>();// 初始化for(int i = 0; i < n; i++) {grip.add(new ArrayList<>());} for(int[] r : roads) {grip.get(r[0]).add(r[1]);grip.get(r[1]).add(r[0]);}int[] size = new int[n]; // 记录子节点的个数long[] cost = new long[n]; // 记录子节点的花费f(grip, seats, 0, -1, size, cost); // 头节点0的父节点是-1return cost[0];}public static void f(ArrayList<ArrayList<Integer>> grip, int seats, int u, int p, int[] size, long[]cost) {size[u] = 1;for(int v : grip.get(u)) {if(v != p) {f(grip, seats, v, u, size, cost);size[u] += size[v];cost[u] += cost[v];cost[u] += (size[v] + seats - 1) / seats;}}}
}