访问完所有房间的第一天
难度:
标签:
题目描述
代码结果
运行时间: 134 ms, 内存: 28.1 MB
/*
思路:
1. 使用Java Stream流的方式来解决该问题。
2. 使用一个数组来记录每个房间的访问次数,通过Stream处理来决定下一个房间。
*/
import java.util.stream.IntStream;
public class VisitRoomsStream {
public int firstDayToVisitAllRooms(int[] nextVisit) {
int n = nextVisit.length;
int[] visitCount = new int[n];
int[] current = new int[]{0}; // 当前位置初始化为房间0
long[] currentDay = new long[]{0};
boolean[] visited = new boolean[n];
IntStream.iterate(0, i -> visited[i] ? -1 : current[0]).filter(i -> i != -1).forEach(i -> {
if (visitCount[current[0]] == 0) {
visited[current[0]] = true;
}
visitCount[current[0]]++;
currentDay[0]++;
if (visitCount[current[0]] % 2 == 1) {
current[0] = nextVisit[current[0]];
} else {
current[0] = (current[0] + 1) % n;
}
});
return (int) (currentDay[0] % (1e9 + 7));
}
public static void main(String[] args) {
VisitRoomsStream vr = new VisitRoomsStream();
int[] nextVisit = {0, 0, 2};
System.out.println(vr.firstDayToVisitAllRooms(nextVisit)); // 输出 6
}
}
解释
方法:
在这个题解中,使用了动态规划的方法。数组 dp 用来记录到达每个房间的第一天的日期编号。初始时,dp[0] = 0,表示第 0 天访问房间 0。对于每个房间 i (从 1 开始),根据题目中的访问规则,如果访问次数为奇数次,则访问 nextVisit[i],否则访问 (i + 1) % n。题解中,dp 的更新公式为 dp[i] = ((dp[i-1] << 1) + 2 - dp[nextVisit[i-1]]) % 1000000007,这个公式是基于之前房间的访问次数和规则计算得出。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在解题算法中,公式 `dp[i] = ((dp[i-1] << 1) + 2 - dp[nextVisit[i-1]]) % 1000000007` 是如何推导出来的?
▷🦆
为什么在初始化动态规划数组 `dp` 时只设置 `dp[0] = 0`,而没有为其他房间设置初始值?
▷🦆
题解中提到移除数组 `v` 的最后一个元素,这样做的具体原因是什么?是否对算法的正确性和最终结果有影响?
▷🦆
动态规划解法中使用的模数 `1000000007` 有什么特别的原因吗,还是只是为了防止整数溢出?
▷