|
| 1 | +from collections import defaultdict |
| 2 | +from typing import List |
| 3 | + |
| 4 | + |
| 5 | +class Solution: |
| 6 | + # Since the max drop location can be 1000, we can store number of people in the |
| 7 | + # car at every location in a hash map. It will take O(1) space. |
| 8 | + # We iterate over every element of trips, and update our hash map. |
| 9 | + # |
| 10 | + # Time: O(1) |
| 11 | + # Space: O(1) |
| 12 | + # Since the number of trips is bounded. |
| 13 | + # |
| 14 | + # Further optimizations: |
| 15 | + # As we will see in the official solution, we could keep only the changes (the |
| 16 | + # delta) in the hash map. |
| 17 | + def carPooling(self, trips: List[List[int]], capacity: int) -> bool: |
| 18 | + counts = defaultdict(int) |
| 19 | + max_count = 0 |
| 20 | + for trip in trips: |
| 21 | + for loc in range(trip[1], trip[2]): |
| 22 | + counts[loc] += trip[0] |
| 23 | + max_count = max(max_count, counts[loc]) |
| 24 | + if max_count > capacity: |
| 25 | + return False |
| 26 | + return True |
| 27 | + |
| 28 | + |
| 29 | +class OfficialSolution: |
| 30 | + """ |
| 31 | + == Overview == |
| 32 | + It is one of the classical problems related to intervals, and we have some similar |
| 33 | + problems such as Meeting Rooms II at LeetCode. Below, two approaches are introduced: |
| 34 | + the simple Time Stamp approach, and the Bucket Sort approach. |
| 35 | + """ |
| 36 | + |
| 37 | + def carPoolingApproach1(self, trips: List[List[int]], capacity: int) -> bool: |
| 38 | + """ |
| 39 | + == Approach 1: Time Stamp == |
| 40 | + == Intuition == |
| 41 | + A simple idea is to go through from the start to end, and check if the actual |
| 42 | + capacity exceeds `capacity`. To know the actual capacity, we just need the number of |
| 43 | + passengers changed at each timestamp. |
| 44 | + We can save the number of passengers changed at each time, sort it by timestamp, and |
| 45 | + finally iterate it to check the actual capacity. |
| 46 | +
|
| 47 | + == Algorithm == |
| 48 | + We will initialize a list to store the number of passengers changed and the |
| 49 | + corresponding timestamp and then sort it. |
| 50 | + Finally, we just need to iterate from the start timestamp to the end timestamp, and |
| 51 | + check if the actual capacity meets the condition. |
| 52 | +
|
| 53 | + == Complexity Analysis == |
| 54 | + Assume N is the length of the trips. |
| 55 | + Time Complexity: O(NlgN) since we need to iterate over trips and sort our timestamp. |
| 56 | + Iterating costs O(N), and sorting costs O(NlgN), and adding together we have |
| 57 | + O(N) + O(NlgN) = O(NlgN). |
| 58 | + Space Complexity: O(N) to store timestamp. |
| 59 | + """ |
| 60 | + timestamp = [] |
| 61 | + for trip in trips: |
| 62 | + timestamp.append([trip[1], trip[0]]) |
| 63 | + timestamp.append([trip[2], -trip[0]]) |
| 64 | + |
| 65 | + timestamp.sort() |
| 66 | + |
| 67 | + used_capacity = 0 |
| 68 | + for time, passenger_change in timestamp: |
| 69 | + used_capacity += passenger_change |
| 70 | + if used_capacity > capacity: |
| 71 | + return False |
| 72 | + |
| 73 | + return True |
| 74 | + |
| 75 | + def carPoolingApproach2(self, trips: List[List[int]], capacity: int) -> bool: |
| 76 | + """ |
| 77 | + == Approach 2: Bucket Sort == |
| 78 | + == Intuition == |
| 79 | + Note that in the problem there is a interesting constraint: |
| 80 | + 0 <= trips[i][1] < trips[i][2] <= 1000 |
| 81 | + What pops into the mind is Bucket Sort, which is a sorting algorithm in O(N) |
| 82 | + time but requires prior knowledge for the range of the data. |
| 83 | + We can use it instead of the normal sorting in this method. |
| 84 | + What we do is initial 1001 buckets, and put the number of passengers changed in |
| 85 | + corresponding buckets, and collect the buckets one by one. |
| 86 | +
|
| 87 | + == Algorithm == |
| 88 | + We will initialize 1001 buckets, iterate `trips`, and save the number of |
| 89 | + passengers changed at i mile in the i-th bucket. |
| 90 | +
|
| 91 | + == Complexity Analysis == |
| 92 | + Assume N is the length of the trip. |
| 93 | + Time Complexity: O(max(N, 10001)), since we need to iterate over trips and then |
| 94 | + iterate over 1001 buckets. |
| 95 | + Space Complexity: O(1001) = O(1) since we have 1001 buckets. |
| 96 | + """ |
| 97 | + timestamp = [0] * 1001 |
| 98 | + for trip in trips: |
| 99 | + timestamp[trip[1]] += trip[0] |
| 100 | + timestamp[trip[2]] -= trip[0] |
| 101 | + |
| 102 | + used_capacity = 0 |
| 103 | + for passenger_change in timestamp: |
| 104 | + used_capacity += passenger_change |
| 105 | + if used_capacity > capacity: |
| 106 | + return False |
| 107 | + |
| 108 | + return True |
0 commit comments