出租车的最大盈利
难度:
标签:
题目描述
代码结果
运行时间: 256 ms, 内存: 33.5 MB
/*
* 使用Java Stream API解决此问题的实现。
* 利用stream进行数据处理和聚合。
*/
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class TaxiProfitStream {
public static long maxProfit(int n, int[][] rides) {
// 通过stream将rides数组转换为以终点为键,利润为值的Map
Map<Integer, Long> profitMap = Arrays.stream(rides)
.collect(Collectors.groupingBy(
ride -> ride[1], // 按终点分组
Collectors.summingLong(ride -> ride[1] - ride[0] + ride[2]) // 计算利润
));
// 初始化dp数组
long[] dp = new long[n + 1];
// 使用IntStream进行范围遍历
IntStream.range(1, n + 1).forEach(i -> {
// dp[i]初始化为dp[i-1]
dp[i] = dp[i - 1];
// 如果profitMap中包含i,更新dp[i]
if (profitMap.containsKey(i)) {
int finalI = i;
dp[i] = Math.max(dp[i],
profitMap.entrySet().stream()
.filter(e -> e.getKey() <= finalI)
.mapToLong(Map.Entry::getValue)
.sum()
);
}
});
// 返回最终的最大利润
return dp[n];
}
public static void main(String[] args) {
int n = 20;
int[][] rides = { {1, 6, 1}, {3, 10, 2}, {10, 12, 3}, {11, 12, 2}, {12, 15, 2}, {13, 18, 1} };
System.out.println(maxProfit(n, rides)); // 输出20
}
}
解释
方法:
本题解采用动态规划的方法解决问题。定义 dp[i] 为到达第 i 个地点时能获得的最大盈利。对于每个地点 i,首先保持 dp[i] 等于 dp[i-1](即不接新的乘客情况下的盈利),然后检查是否有乘客在此地点结束行程。如果有,则尝试接该乘客并计算接此乘客所能获得的盈利(包括行程费和小费),并更新 dp[i]。对于每个结束点 i,查看所有在此结束的行程,计算如果接此乘客从他们的起始点 start 到 i 所能得到的盈利,更新 dp[i] 为最大值。最终,dp[n] 将是从 1 到 n 地点能获得的最大盈利。
时间复杂度:
O(n + m)
空间复杂度:
O(n + m)
代码细节讲解
🦆
为什么在动态规划数组dp中,dp[i]的初始值设置为dp[i-1],而不是其他值?
▷🦆
如何处理乘客信息存储在rideMap中,以便高效地检索每个结束点的所有起始点和小费信息?
▷🦆
在乘客结束点相同的情况下,如果存在多个乘客选项,如何确保选择的乘客能够最大化盈利?
▷🦆
动态规划解法中,为什么选择更新dp[i]时只考虑当前结束点的乘客,而不是所有可能的乘客组合?
▷