LeetCode in Kotlin

146. LRU Cache

Medium

Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.

Implement the LRUCache class:

The functions get and put must each run in O(1) average time complexity.

Example 1:

Input [“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]

Output: [null, null, null, 1, null, -1, null, -1, 3, 4]

Explanation:

LRUCache lRUCache = new LRUCache(2);

lRUCache.put(1, 1); // cache is {1=1}

lRUCache.put(2, 2); // cache is {1=1, 2=2}

lRUCache.get(1); // return 1

lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}

lRUCache.get(2); // returns -1 (not found)

lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3}

lRUCache.get(1); // return -1 (not found)

lRUCache.get(3); // return 3

lRUCache.get(4); // return 4

Constraints:

Solution

class LRUCache(capacity: Int) {
    private val nodeMap = HashMap<Int, Node>()
    private val head = Node()
    private val tail = Node()
    private var cacheCapacity = 0

    init {
        head.next = tail
        tail.prev = head
        cacheCapacity = capacity
    }

    fun get(key: Int): Int {
        return if (!nodeMap.containsKey(key)) {
            -1
        } else {
            val requiredNode = nodeMap.getValue(key)
            update(requiredNode)
            requiredNode.value
        }
    }

    fun put(key: Int, value: Int) {
        if (nodeMap.containsKey(key)) {
            val requiredNode = nodeMap.getValue(key)
            requiredNode.value = value
            update(requiredNode)
        } else {
            val newNode = Node(key = key, value = value)
            if (nodeMap.size >= cacheCapacity) {
                val nodeToDelete = tail.prev!!
                remove(nodeToDelete)
                nodeMap.remove(nodeToDelete.key)
            }
            add(newNode)
            nodeMap.put(key, newNode)
        }
    }

    fun add(node: Node) {
        val after = head.next
        head.next = node
        node.prev = head
        node.next = after
        after?.prev = node
    }

    private fun remove(node: Node) {
        val before = node.prev
        val after = node.next

        before?.next = after
        after?.prev = before
    }

    private fun update(node: Node) {
        remove(node)
        add(node)
    }

    data class Node(var key: Int = -1, var value: Int = -1, var next: Node? = null, var prev: Node? = null)
}

/*
 * Your LRUCache object will be instantiated and called as such:
 * var obj = LRUCache(capacity)
 * var param_1 = obj.get(key)
 * obj.put(key,value)
 */
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy