Leetcode LRU緩存,數組+結構體實現

1、算法思路node

LRUCache類有如下函數和變量:算法

  • LRUCache(int capacity): capacity是當前對象可以存儲的鍵值對(key,value)最大個數。
  • int get(int key): 根據指定的key尋找value值,若沒有找到key就返回-1
  • void put(int key, int value): 存儲一個新的鍵值對(key,value),若是key已經存在,就更新value,若是當前已達最大容量,就將最近最少使用的鍵值對替換。
  • void show(): 查看當前全部鍵值對信息。(題目並無要求書寫這個函數,只是爲了方便調試)。
  • int size: 當前所存儲的鍵值對個數。
  • int max_size: 最大鍵值對個數(對應構造函數的capacity)。
  • Node *list:鍵值對數組。

Node結構體的定義:數組

typedef struct LRUCacheNode {
    int key;
    int value;
    int count;
} Node;

其中key,value構成了鍵值對(key,value),count表示已有多久沒有使用。當一個鍵值對節點(Node)被第一次插入、查詢或是修改,其count都會被置零,而其餘節點的count自增。已達到最大存儲量後,插入節點會修改全部節點中count最大的,修改完畢(也就是value值被更新後),count會被置零,而其餘節點的count依然會自增。緩存

2、代碼演示函數

LRUCache(int capacity) {
        max_size = capacity;
        size = 0;
        list = new Node[max_size];
}

LRUCache的構造函數僅僅初始化max_size,size和list。三者的定義以下:優化

private:
    int size;
    int max_size;
    Node *list;

接下來是get函數,比較簡單,依次遍歷list並尋找符合要求的節點,不要忘記將符合要求的節點的count置零,以及將其餘節點的count自增:spa

int get(int key) {
        int value = -1;
        for (int i = 0; i < size; ++i) {
            Node *tmp = &list[i];
            if (tmp->key == key) {
                tmp->count = 0;
                value = tmp->value;
            } else {
                tmp->count++;
            }
        }
        return value;
}

接下來講重點——put函數:調試

void put(int key, int value) {
        bool contains = false;
        for (int i = 0; i < size; ++i) {
            Node *tmp = &list[i];
            if (tmp->key == key) {
                tmp->count = 0;
                tmp->value = value;
                contains = true;
            } else {
                tmp->count++;
            }
        }

        if (contains) { return; }

        if (size >= max_size) {
            int max_count = -1;
            Node *max_node;
            for (int i = 0; i < size; ++i) {
                Node *tmp = &list[i];
                if (tmp->count > max_count) {
                    max_count = tmp->count;
                    max_node = tmp;
                }
            }
            max_node->key = key;
            max_node->value = value;
            max_node->count = 0;
        } else {
            Node n;
            n.key = key;
            n.value = value;
            n.count = 0;
            list[size++] = n;
        }
}

 put函數首先在list中尋找(key,value)是否存在,是則僅更新節點並返回。若是沒有找到節點,接下來判斷list是否已滿:若是沒有滿,就將(key,value)存儲到list數組;若是已經滿了,首先根據count大小,尋找出count最大的節點,將其修改(此步並不須要將其餘節點count自增,由於在第一步尋找(key,value)是否存在是已經自增過了)。code

接下來是show函數,能夠自行調整樣式:對象

void show() {
        for (int i = 0; i < size; ++i) {
            Node *tmp = &list[i];
            cout << tmp->key << "\t" << tmp->value << "\t" << tmp->count << "\n";
        }
}

main函數調試:

int main() {
    LRUCache cache = LRUCache(2 /* 緩存容量 */ );
    cache.put(1, 1);
    cache.put(2, 2);
    cout << cache.get(1) << "\n";       // 返回  1
    cache.put(3, 3);    // 該操做會使得密鑰 2 做廢
    cout << cache.get(2) << "\n";       // 返回 -1 (未找到)
    cache.put(4, 4);    // 該操做會使得密鑰 1 做廢
    cout << cache.get(1) << "\n";       // 返回 -1 (未找到)
    cout << cache.get(3) << "\n";       // 返回  3
    cout << cache.get(4) << "\n";       // 返回  4

    return 0;
}

main函數輸出:

1
-1
-1
3
4

3、提交結果

 

 執行用時並不理想,有待優化。

相關文章
相關標籤/搜索