Design and implement an in-memory cache that evicts the least-recently-used item when its capacity is reached and also supports per-entry time-to-live (TTL). Your LRUCacheWithTTL class must support three operations:
get(key) → returns the value of the key if the key exists and has not expired; otherwise returns -1. Every successful get refreshes the entry’s “recently used” order.
put(key, value, ttl) → inserts or updates the value of the key with the given TTL (in milliseconds). If the key already exists, overwrite its value and reset its TTL. If the number of entries exceeds capacity after the insertion, first evict any already-expired entries (in any order); if still over capacity, evict the least-recently-used non-expired entry. A TTL of 0 or None means the entry never expires.
size() → returns the current number of non-expired entries.
All three operations must run in average O(1) time. You may assume that the system clock is monotonic and that you can read the current timestamp in O(1).