This problem requires designing a LogSystem
that can store logs with timestamps and retrieve logs within a specified range based on a given granularity. The solution uses a simple approach leveraging string manipulation and comparison for efficiency.
The core idea is to store logs as pairs of (ID, timestamp). Retrieving logs involves comparing truncated timestamps based on the specified granularity.
put(id, timestamp)
: This method simply appends the log (ID, timestamp) to a list of logs. The timestamp is stored as a string in "Year:Month:Day:Hour:Minute:Second" format. This operation has a time complexity of O(1) as it involves a single append operation to the list.
retrieve(start, end, granularity)
: This is where the main logic resides.
granularity
map is used to determine the index up to which the timestamp string needs to be truncated (e.g., "Year" -> truncate up to the 4th character, "Day" -> up to the 10th character).start
and end
timestamps are truncated based on the granularity
.granularity
.start
and end
timestamps. If it falls within the range (inclusive), the corresponding ID is added to the result list.Time Complexity:
put()
: O(1) - Constant time for appending to the list.retrieve()
: O(n) - Linear time complexity due to the iteration through the list of logs.Space Complexity:
logs
list.class LogSystem:
def __init__(self):
self.logs = [] # List to store logs as (id, timestamp) pairs
self.d = { # Map for granularity to index mapping
"Year": 4,
"Month": 7,
"Day": 10,
"Hour": 13,
"Minute": 16,
"Second": 19,
}
def put(self, id: int, timestamp: str) -> None:
self.logs.append((id, timestamp))
def retrieve(self, start: str, end: str, granularity: str) -> List[int]:
i = self.d[granularity] # Get the truncation index
return [id for id, ts in self.logs if start[:i] <= ts[:i] <= end[:i]] #Efficient list comprehension for filtering
The Python code uses a list comprehension for concisely filtering logs based on the truncated timestamps. Other language implementations (Java, C++, Go) follow a similar structure, using appropriate data structures and syntax for their respective languages. The core algorithmic approach remains consistent across all implementations.