diff --git a/solution/2500-2599/2532.Time to Cross a Bridge/README_EN.md b/solution/2500-2599/2532.Time to Cross a Bridge/README_EN.md index 8758a7927cbd1..b5cb136e98acf 100644 --- a/solution/2500-2599/2532.Time to Cross a Bridge/README_EN.md +++ b/solution/2500-2599/2532.Time to Cross a Bridge/README_EN.md @@ -107,7 +107,30 @@ From 49 to 50: worker 0 crosses the bridge to the left. -### Solution 1 +### Solution 1: Priority Queue (Max-Heap and Min-Heap) + Simulation + +First, we sort the workers by efficiency in descending order, so the worker with the highest index has the lowest efficiency. + +Next, we use four priority queues to simulate the state of the workers: + +- `wait_in_left`: Max-heap, storing the indices of workers currently waiting on the left bank; +- `wait_in_right`: Max-heap, storing the indices of workers currently waiting on the right bank; +- `work_in_left`: Min-heap, storing the time when workers currently working on the left bank finish placing boxes and the indices of the workers; +- `work_in_right`: Min-heap, storing the time when workers currently working on the right bank finish picking up boxes and the indices of the workers. + +Initially, all workers are on the left bank, so `wait_in_left` stores the indices of all workers. We use the variable `cur` to record the current time. + +Then, we simulate the entire process. First, we check if any worker in `work_in_left` has finished placing boxes at the current time. If so, we move the worker to `wait_in_left` and remove the worker from `work_in_left`. Similarly, we check if any worker in `work_in_right` has finished picking up boxes. If so, we move the worker to `wait_in_right` and remove the worker from `work_in_right`. + +Next, we check if there are any workers waiting on the left bank at the current time, denoted as `left_to_go`. At the same time, we check if there are any workers waiting on the right bank, denoted as `right_to_go`. If there are no workers waiting to cross the river, we directly update `cur` to the next time when a worker finishes placing boxes and continue the simulation. + +If `right_to_go` is `true`, we take a worker from `wait_in_right`, update `cur` to the current time plus the time it takes for the worker to cross from the right bank to the left bank. If all workers have crossed to the right bank at this point, we directly return `cur` as the answer; otherwise, we move the worker to `work_in_left`. + +If `left_to_go` is `true`, we take a worker from `wait_in_left`, update `cur` to the current time plus the time it takes for the worker to cross from the left bank to the right bank, then move the worker to `work_in_right` and decrement the number of boxes. + +Repeat the above process until the number of boxes is zero. At this point, `cur` is the answer. + +The time complexity is $O(n \times \log k)$, and the space complexity is $O(k)$. Here, $n$ and $k$ are the number of workers and the number of boxes, respectively. diff --git a/solution/2500-2599/2534.Time Taken to Cross the Door/README.md b/solution/2500-2599/2534.Time Taken to Cross the Door/README.md index a71d438dc295f..054166f0dbbb1 100644 --- a/solution/2500-2599/2534.Time Taken to Cross the Door/README.md +++ b/solution/2500-2599/2534.Time Taken to Cross the Door/README.md @@ -83,32 +83,217 @@ tags: -### 方法一 +### 方法一:队列 + 模拟 + +我们定义两个队列,其中 $q[0]$ 存放想要进入的人的编号,而 $q[1]$ 存放想要离开的人的编号。 + +我们维护一个时间 $t$,表示当前时间,一个状态 $st$,表示当前门的状态,当 $st = 1$ 表示门没使用或者上一秒有人离开,当 $st = 0$ 表示上一秒有人进入。初始时 $t = 0$,而 $st = 1$。 + +我们遍历数组 $\textit{arrival}$,对于每个人,如果当前时间 $t$ 小于等于该人到达门前的时间 $arrival[i]$,我们将该人的编号加入对应的队列 $q[\text{state}[i]]$ 中。 + +然后我们判断当前队列 $q[0]$ 和 $q[1]$ 是否都不为空,如果都不为空,我们将 $q[st]$ 队列的队首元素出队,并将当前时间 $t$ 赋值给该人的通过时间;如果只有一个队列不为空,我们根据哪个队列不为空,更新 $st$ 的值,然后将该队列的队首元素出队,并将当前时间 $t$ 赋值给该人的通过时间;如果两个队列都为空,我们将 $st$ 的值更新为 $1$,表示门没使用。 + +接下来,我们将时间 $t$ 自增 $1$,继续遍历数组 $\textit{arrival}$,直到所有人都通过门。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 表示数组 $\textit{arrival}$ 的长度。 #### Python3 ```python - +class Solution: + def timeTaken(self, arrival: List[int], state: List[int]) -> List[int]: + q = [deque(), deque()] + n = len(arrival) + t = i = 0 + st = 1 + ans = [0] * n + while i < n or q[0] or q[1]: + while i < n and arrival[i] <= t: + q[state[i]].append(i) + i += 1 + if q[0] and q[1]: + ans[q[st].popleft()] = t + elif q[0] or q[1]: + st = 0 if q[0] else 1 + ans[q[st].popleft()] = t + else: + st = 1 + t += 1 + return ans ``` #### Java ```java - +class Solution { + public int[] timeTaken(int[] arrival, int[] state) { + Deque[] q = new Deque[2]; + Arrays.setAll(q, i -> new ArrayDeque<>()); + int n = arrival.length; + int t = 0, i = 0, st = 1; + int[] ans = new int[n]; + while (i < n || !q[0].isEmpty() || !q[1].isEmpty()) { + while (i < n && arrival[i] <= t) { + q[state[i]].add(i++); + } + if (!q[0].isEmpty() && !q[1].isEmpty()) { + ans[q[st].poll()] = t; + } else if (!q[0].isEmpty() || !q[1].isEmpty()) { + st = q[0].isEmpty() ? 1 : 0; + ans[q[st].poll()] = t; + } else { + st = 1; + } + ++t; + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector timeTaken(vector& arrival, vector& state) { + int n = arrival.size(); + queue q[2]; + int t = 0, i = 0, st = 1; + vector ans(n); + + while (i < n || !q[0].empty() || !q[1].empty()) { + while (i < n && arrival[i] <= t) { + q[state[i]].push(i++); + } + + if (!q[0].empty() && !q[1].empty()) { + ans[q[st].front()] = t; + q[st].pop(); + } else if (!q[0].empty() || !q[1].empty()) { + st = q[0].empty() ? 1 : 0; + ans[q[st].front()] = t; + q[st].pop(); + } else { + st = 1; + } + + ++t; + } + + return ans; + } +}; ``` #### Go ```go +func timeTaken(arrival []int, state []int) []int { + n := len(arrival) + q := [2][]int{} + t, i, st := 0, 0, 1 + ans := make([]int, n) + + for i < n || len(q[0]) > 0 || len(q[1]) > 0 { + for i < n && arrival[i] <= t { + q[state[i]] = append(q[state[i]], i) + i++ + } + + if len(q[0]) > 0 && len(q[1]) > 0 { + ans[q[st][0]] = t + q[st] = q[st][1:] + } else if len(q[0]) > 0 || len(q[1]) > 0 { + if len(q[0]) == 0 { + st = 1 + } else { + st = 0 + } + ans[q[st][0]] = t + q[st] = q[st][1:] + } else { + st = 1 + } + + t++ + } + + return ans +} +``` + +#### TypeScript + +```ts +function timeTaken(arrival: number[], state: number[]): number[] { + const n = arrival.length; + const q: number[][] = [[], []]; + let [t, i, st] = [0, 0, 1]; + const ans: number[] = Array(n).fill(0); + + while (i < n || q[0].length || q[1].length) { + while (i < n && arrival[i] <= t) { + q[state[i]].push(i++); + } + + if (q[0].length && q[1].length) { + ans[q[st][0]] = t; + q[st].shift(); + } else if (q[0].length || q[1].length) { + st = q[0].length ? 0 : 1; + ans[q[st][0]] = t; + q[st].shift(); + } else { + st = 1; + } + + t++; + } + + return ans; +} +``` +#### Rust + +```rust +use std::collections::VecDeque; + +impl Solution { + pub fn time_taken(arrival: Vec, state: Vec) -> Vec { + let n = arrival.len(); + let mut q = vec![VecDeque::new(), VecDeque::new()]; + let mut t = 0; + let mut i = 0; + let mut st = 1; + let mut ans = vec![-1; n]; + + while i < n || !q[0].is_empty() || !q[1].is_empty() { + while i < n && arrival[i] <= t { + q[state[i] as usize].push_back(i); + i += 1; + } + + if !q[0].is_empty() && !q[1].is_empty() { + ans[*q[st].front().unwrap()] = t; + q[st].pop_front(); + } else if !q[0].is_empty() || !q[1].is_empty() { + st = if q[0].is_empty() { 1 } else { 0 }; + ans[*q[st].front().unwrap()] = t; + q[st].pop_front(); + } else { + st = 1; + } + + t += 1; + } + + ans + } +} ``` diff --git a/solution/2500-2599/2534.Time Taken to Cross the Door/README_EN.md b/solution/2500-2599/2534.Time Taken to Cross the Door/README_EN.md index c43f24d9e26e0..a997cabe55d04 100644 --- a/solution/2500-2599/2534.Time Taken to Cross the Door/README_EN.md +++ b/solution/2500-2599/2534.Time Taken to Cross the Door/README_EN.md @@ -82,32 +82,217 @@ tags: -### Solution 1 +### Solution 1: Queue + Simulation + +We define two queues, where $q[0]$ stores the indices of people who want to enter, and $q[1]$ stores the indices of people who want to exit. + +We maintain a variable $t$ to represent the current time, and a variable $st$ to represent the current state of the door. When $st = 1$, it means the door is not in use or someone exited in the previous second. When $st = 0$, it means someone entered in the previous second. Initially, $t = 0$ and $st = 1$. + +We traverse the array $\textit{arrival}$. For each person, if the current time $t$ is less than or equal to the time the person arrives at the door $\textit{arrival}[i]$, we add the person's index to the corresponding queue $q[\text{state}[i]]$. + +Then we check if both queues $q[0]$ and $q[1]$ are not empty. If both are not empty, we dequeue the front element from the queue $q[st]$ and assign the current time $t$ to the person's passing time. If only one queue is not empty, we update the value of $st$ based on which queue is not empty, then dequeue the front element from that queue and assign the current time $t$ to the person's passing time. If both queues are empty, we update the value of $st$ to $1$, indicating the door is not in use. + +Next, we increment the time $t$ by $1$ and continue traversing the array $\textit{arrival}$ until all people have passed through the door. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ represents the length of the array $\textit{arrival}$. #### Python3 ```python - +class Solution: + def timeTaken(self, arrival: List[int], state: List[int]) -> List[int]: + q = [deque(), deque()] + n = len(arrival) + t = i = 0 + st = 1 + ans = [0] * n + while i < n or q[0] or q[1]: + while i < n and arrival[i] <= t: + q[state[i]].append(i) + i += 1 + if q[0] and q[1]: + ans[q[st].popleft()] = t + elif q[0] or q[1]: + st = 0 if q[0] else 1 + ans[q[st].popleft()] = t + else: + st = 1 + t += 1 + return ans ``` #### Java ```java - +class Solution { + public int[] timeTaken(int[] arrival, int[] state) { + Deque[] q = new Deque[2]; + Arrays.setAll(q, i -> new ArrayDeque<>()); + int n = arrival.length; + int t = 0, i = 0, st = 1; + int[] ans = new int[n]; + while (i < n || !q[0].isEmpty() || !q[1].isEmpty()) { + while (i < n && arrival[i] <= t) { + q[state[i]].add(i++); + } + if (!q[0].isEmpty() && !q[1].isEmpty()) { + ans[q[st].poll()] = t; + } else if (!q[0].isEmpty() || !q[1].isEmpty()) { + st = q[0].isEmpty() ? 1 : 0; + ans[q[st].poll()] = t; + } else { + st = 1; + } + ++t; + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector timeTaken(vector& arrival, vector& state) { + int n = arrival.size(); + queue q[2]; + int t = 0, i = 0, st = 1; + vector ans(n); + + while (i < n || !q[0].empty() || !q[1].empty()) { + while (i < n && arrival[i] <= t) { + q[state[i]].push(i++); + } + + if (!q[0].empty() && !q[1].empty()) { + ans[q[st].front()] = t; + q[st].pop(); + } else if (!q[0].empty() || !q[1].empty()) { + st = q[0].empty() ? 1 : 0; + ans[q[st].front()] = t; + q[st].pop(); + } else { + st = 1; + } + + ++t; + } + + return ans; + } +}; ``` #### Go ```go +func timeTaken(arrival []int, state []int) []int { + n := len(arrival) + q := [2][]int{} + t, i, st := 0, 0, 1 + ans := make([]int, n) + + for i < n || len(q[0]) > 0 || len(q[1]) > 0 { + for i < n && arrival[i] <= t { + q[state[i]] = append(q[state[i]], i) + i++ + } + + if len(q[0]) > 0 && len(q[1]) > 0 { + ans[q[st][0]] = t + q[st] = q[st][1:] + } else if len(q[0]) > 0 || len(q[1]) > 0 { + if len(q[0]) == 0 { + st = 1 + } else { + st = 0 + } + ans[q[st][0]] = t + q[st] = q[st][1:] + } else { + st = 1 + } + + t++ + } + + return ans +} +``` + +#### TypeScript + +```ts +function timeTaken(arrival: number[], state: number[]): number[] { + const n = arrival.length; + const q: number[][] = [[], []]; + let [t, i, st] = [0, 0, 1]; + const ans: number[] = Array(n).fill(0); + + while (i < n || q[0].length || q[1].length) { + while (i < n && arrival[i] <= t) { + q[state[i]].push(i++); + } + + if (q[0].length && q[1].length) { + ans[q[st][0]] = t; + q[st].shift(); + } else if (q[0].length || q[1].length) { + st = q[0].length ? 0 : 1; + ans[q[st][0]] = t; + q[st].shift(); + } else { + st = 1; + } + + t++; + } + + return ans; +} +``` +#### Rust + +```rust +use std::collections::VecDeque; + +impl Solution { + pub fn time_taken(arrival: Vec, state: Vec) -> Vec { + let n = arrival.len(); + let mut q = vec![VecDeque::new(), VecDeque::new()]; + let mut t = 0; + let mut i = 0; + let mut st = 1; + let mut ans = vec![-1; n]; + + while i < n || !q[0].is_empty() || !q[1].is_empty() { + while i < n && arrival[i] <= t { + q[state[i] as usize].push_back(i); + i += 1; + } + + if !q[0].is_empty() && !q[1].is_empty() { + ans[*q[st].front().unwrap()] = t; + q[st].pop_front(); + } else if !q[0].is_empty() || !q[1].is_empty() { + st = if q[0].is_empty() { 1 } else { 0 }; + ans[*q[st].front().unwrap()] = t; + q[st].pop_front(); + } else { + st = 1; + } + + t += 1; + } + + ans + } +} ``` diff --git a/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.cpp b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.cpp new file mode 100644 index 0000000000000..4a9acd74e5d9a --- /dev/null +++ b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.cpp @@ -0,0 +1,30 @@ +class Solution { +public: + vector timeTaken(vector& arrival, vector& state) { + int n = arrival.size(); + queue q[2]; + int t = 0, i = 0, st = 1; + vector ans(n); + + while (i < n || !q[0].empty() || !q[1].empty()) { + while (i < n && arrival[i] <= t) { + q[state[i]].push(i++); + } + + if (!q[0].empty() && !q[1].empty()) { + ans[q[st].front()] = t; + q[st].pop(); + } else if (!q[0].empty() || !q[1].empty()) { + st = q[0].empty() ? 1 : 0; + ans[q[st].front()] = t; + q[st].pop(); + } else { + st = 1; + } + + ++t; + } + + return ans; + } +}; diff --git a/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.go b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.go new file mode 100644 index 0000000000000..74b29c51a1194 --- /dev/null +++ b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.go @@ -0,0 +1,32 @@ +func timeTaken(arrival []int, state []int) []int { + n := len(arrival) + q := [2][]int{} + t, i, st := 0, 0, 1 + ans := make([]int, n) + + for i < n || len(q[0]) > 0 || len(q[1]) > 0 { + for i < n && arrival[i] <= t { + q[state[i]] = append(q[state[i]], i) + i++ + } + + if len(q[0]) > 0 && len(q[1]) > 0 { + ans[q[st][0]] = t + q[st] = q[st][1:] + } else if len(q[0]) > 0 || len(q[1]) > 0 { + if len(q[0]) == 0 { + st = 1 + } else { + st = 0 + } + ans[q[st][0]] = t + q[st] = q[st][1:] + } else { + st = 1 + } + + t++ + } + + return ans +} diff --git a/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.java b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.java new file mode 100644 index 0000000000000..f9bfaeb80e70d --- /dev/null +++ b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.java @@ -0,0 +1,24 @@ +class Solution { + public int[] timeTaken(int[] arrival, int[] state) { + Deque[] q = new Deque[2]; + Arrays.setAll(q, i -> new ArrayDeque<>()); + int n = arrival.length; + int t = 0, i = 0, st = 1; + int[] ans = new int[n]; + while (i < n || !q[0].isEmpty() || !q[1].isEmpty()) { + while (i < n && arrival[i] <= t) { + q[state[i]].add(i++); + } + if (!q[0].isEmpty() && !q[1].isEmpty()) { + ans[q[st].poll()] = t; + } else if (!q[0].isEmpty() || !q[1].isEmpty()) { + st = q[0].isEmpty() ? 1 : 0; + ans[q[st].poll()] = t; + } else { + st = 1; + } + ++t; + } + return ans; + } +} diff --git a/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.py b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.py new file mode 100644 index 0000000000000..4faa330b56855 --- /dev/null +++ b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.py @@ -0,0 +1,20 @@ +class Solution: + def timeTaken(self, arrival: List[int], state: List[int]) -> List[int]: + q = [deque(), deque()] + n = len(arrival) + t = i = 0 + st = 1 + ans = [0] * n + while i < n or q[0] or q[1]: + while i < n and arrival[i] <= t: + q[state[i]].append(i) + i += 1 + if q[0] and q[1]: + ans[q[st].popleft()] = t + elif q[0] or q[1]: + st = 0 if q[0] else 1 + ans[q[st].popleft()] = t + else: + st = 1 + t += 1 + return ans diff --git a/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.rs b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.rs new file mode 100644 index 0000000000000..c6a68a0d0a4a2 --- /dev/null +++ b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.rs @@ -0,0 +1,34 @@ +use std::collections::VecDeque; + +impl Solution { + pub fn time_taken(arrival: Vec, state: Vec) -> Vec { + let n = arrival.len(); + let mut q = vec![VecDeque::new(), VecDeque::new()]; + let mut t = 0; + let mut i = 0; + let mut st = 1; + let mut ans = vec![-1; n]; + + while i < n || !q[0].is_empty() || !q[1].is_empty() { + while i < n && arrival[i] <= t { + q[state[i] as usize].push_back(i); + i += 1; + } + + if !q[0].is_empty() && !q[1].is_empty() { + ans[*q[st].front().unwrap()] = t; + q[st].pop_front(); + } else if !q[0].is_empty() || !q[1].is_empty() { + st = if q[0].is_empty() { 1 } else { 0 }; + ans[*q[st].front().unwrap()] = t; + q[st].pop_front(); + } else { + st = 1; + } + + t += 1; + } + + ans + } +} diff --git a/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.ts b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.ts new file mode 100644 index 0000000000000..3cb15ebec5bf0 --- /dev/null +++ b/solution/2500-2599/2534.Time Taken to Cross the Door/Solution.ts @@ -0,0 +1,27 @@ +function timeTaken(arrival: number[], state: number[]): number[] { + const n = arrival.length; + const q: number[][] = [[], []]; + let [t, i, st] = [0, 0, 1]; + const ans: number[] = Array(n).fill(0); + + while (i < n || q[0].length || q[1].length) { + while (i < n && arrival[i] <= t) { + q[state[i]].push(i++); + } + + if (q[0].length && q[1].length) { + ans[q[st][0]] = t; + q[st].shift(); + } else if (q[0].length || q[1].length) { + st = q[0].length ? 0 : 1; + ans[q[st][0]] = t; + q[st].shift(); + } else { + st = 1; + } + + t++; + } + + return ans; +}