首页 > 其他分享 >Leetcode 146 LRUCache

Leetcode 146 LRUCache

时间:2023-08-19 15:56:54浏览次数:32  
标签:146 node obj Node key table hash Leetcode LRUCache

/*
 *
 * Copyright (C) 2023-08-18 13:51 zxinlog <[email protected]>
 *
 */

#include <func.h>
#define N 1000

// 普通Node
typedef struct Node {
    int key;
    int value;
    struct Node *prev;
    struct Node *next;
} Node;

// 定义 HashNode
typedef struct HashNode {
    int key;
    Node *node;
    struct HashNode *next;
} HashNode;

// 定义HashTable
typedef struct HashTable {
    HashNode *arr[N];
    int capacity;
} HashTable;

// 定义LRUCache
typedef struct {
    Node *head;
    Node *tail;
    int capacity;
    int size;
    HashTable *hash_table;
} LRUCache;

// function begin: --------------------------------------------
Node *initNode();
HashTable *initHashTable();
Node *findHashTable(HashTable *hash_table, int key);
LRUCache *lRUCacheCreate(int capacity);
Node *findHashTable(HashTable *hash_table, int key);
void removeHashTable(HashTable *hash_table, int key);
void insertHashTable(HashTable *hash_table, int key, Node *node);
int lRUCacheGet(LRUCache *obj, int key);
Node *removeHead(LRUCache *obj);
void addTail(LRUCache *obj, Node *node);
void lRUCachePut(LRUCache *obj, int key, int value);
void lRUCacheFree(LRUCache *obj);
// function end: --------------------------------------------

Node *initNode() {
    Node *node = (Node *) malloc(sizeof(Node));
    node->prev = NULL;
    node->next = NULL;
    return node;
}

HashTable *initHashTable() {
    HashTable *hash_table = (HashTable *) malloc(sizeof(HashTable));
    hash_table->capacity = N;
    for (int i = 0; i < N; i++) {
        hash_table->arr[i] = NULL;
    }
    return hash_table;
}

LRUCache *lRUCacheCreate(int capacity) {
    LRUCache *cache = (LRUCache *) malloc(sizeof(LRUCache));
    cache->head = initNode();
    cache->tail = initNode();
    cache->head->next = cache->tail;
    cache->tail->prev = cache->head;
    cache->capacity = capacity;
    cache->size = 0;
    cache->hash_table = initHashTable();
    return cache;
}

// HashTable 查找
Node *findHashTable(HashTable *hash_table, int key) {
    int index = key < 0 ? (key % hash_table->capacity) + (hash_table->capacity - 1) : (key % hash_table->capacity);
    HashNode *pnode = hash_table->arr[index];
    while (pnode != NULL) {
        if (pnode->key == key) {
            return pnode->node;
        }
        pnode = pnode->next;
    }
    return NULL;
}

void removeHashTable(HashTable *hash_table, int key) {
    int index = key < 0 ? (key % hash_table->capacity) + (hash_table->capacity - 1) : (key % hash_table->capacity);
    HashNode *p1 = NULL;
    HashNode *p2 = hash_table->arr[index];
    // NULL
    if (p2 == NULL) {
        return;
    }
    // p2 is the hash_node what will delete.
    else if (p2->key == key) {
        hash_table->arr[index] = p2->next;
        free(p2);
        return;
    }
    // p2 is not the hash_node to delete.
    //  双指针
    while (p2 != NULL && p2->key != key) {
        p1 = p2;
        p2 = p2->next;
    }
    if (p1 != NULL && p2 != NULL) {
        p1->next = p2->next;
        free(p2);
        return;
    }
}

void insertHashTable(HashTable *hash_table, int key, Node *node) {
    HashNode *hash_node = (HashNode *) malloc(sizeof(HashNode));
    hash_node->node = node;
    hash_node->key = key;
    int index = key < 0 ? (key % hash_table->capacity) + (hash_table->capacity - 1) : (key % hash_table->capacity);
    hash_node->next = hash_table->arr[index];
    hash_table->arr[index] = hash_node;
}
int lRUCacheGet(LRUCache *obj, int key) {
    Node *pnode = findHashTable(obj->hash_table, key);
    if (pnode == NULL) {
        return -1;
    } else {
        if (obj->head->next != obj->tail) {
            pnode->prev->next = pnode->next;
            pnode->next->prev = pnode->prev;
            addTail(obj, pnode);
        }
        return pnode->value;
    }
}

Node *removeHead(LRUCache *obj) {
    Node *node = obj->head->next;
    obj->head->next = node->next;
    node->next->prev = obj->head;
    return node;
}

void addTail(LRUCache *obj, Node *node) {
    node->next = obj->tail;
    node->prev = obj->tail->prev;
    obj->tail->prev->next = node;
    obj->tail->prev = node;
}

void lRUCachePut(LRUCache *obj, int key, int value) {
    Node *pnode = findHashTable(obj->hash_table, key);

    // 没有且容量没满
    if (pnode == NULL && obj->size < obj->capacity) {
        Node *node = (Node *) malloc(sizeof(Node));
        node->key = key;
        node->value = value;
        node->prev = NULL;
        node->next = NULL;
        addTail(obj, node);
        insertHashTable(obj->hash_table, node->key, node);
        ++obj->size;
    }
    // 没有且容量满了
    else if (pnode == NULL && obj->size == obj->capacity) {
        // printf("obj->size == obj->capacity\n");
        Node *node = removeHead(obj);
        removeHashTable(obj->hash_table, node->key);
        node->key = key;
        node->value = value;
        addTail(obj, node);
        insertHashTable(obj->hash_table, node->key, node);
    }
    // 有
    else if (pnode != NULL) {
        pnode->value = value;
        if (pnode == obj->head->prev) {
            return;
        } else {
            pnode->prev->next = pnode->next;
            pnode->next->prev = pnode->prev;
            addTail(obj, pnode);
        }
    }
}

void lRUCacheFree(LRUCache *obj) {
    Node *p1;
    Node *p2 = obj->head->next;
    while (p2 != obj->tail) {
        p1 = p2;
        removeHashTable(obj->hash_table, p2->key);
        p2 = p2->next;
        free(p1);
    }
    free(obj->head);
    free(obj->tail);
    free(obj->hash_table);
    free(obj);
}

void showCache(LRUCache *cache) {
    Node *p = cache->head->next;
    while (p != cache->tail) {
        printf("(%d,%d)  ", p->key, p->value);
        p = p->next;
    }
    printf("\n");
}

int main() {
    LRUCache *cache = lRUCacheCreate(3);
    lRUCachePut(cache, 1, 2);
    lRUCachePut(cache, 2, 4);
    showCache(cache);
    lRUCacheFree(cache);
}

标签:146,node,obj,Node,key,table,hash,Leetcode,LRUCache
From: https://www.cnblogs.com/zxinlog/p/17642553.html

相关文章

  • LeetCode 1020.飞地的数量
    1.题目:给你一个大小为 mxn 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数......
  • 【LeetCode1384. 按年度列出销售总额】MySQL使用with recursive根据开始日期和结束日
    题目地址https://leetcode.cn/problems/total-sales-amount-by-year/description/代码WITHRECURSIVEDateSeriesAS(SELECTproduct_id,period_startASsale_date,period_end,average_daily_salesFROMSales--Assumingyourtablenameissales_dataUN......
  • 【LeetCode2199. 找到每篇文章的主题】字符串处理题,使用MySQL里的group_concat和LOCAT
    题目地址https://leetcode.cn/problems/finding-the-topic-of-each-post/description/代码witht1as(selectp.*,k.*fromPostspleftjoinKeywordskonLOCATE(LOWER(CONCAT('',word,'')),LOWER(CONCAT('',conte......
  • Leetcode 142. 环形链表II(Linked list cycle ii)
    题目链接给定一个链表的头节点head,返回链表开始入环的第一个节点。.如果链表无环,则返回null.如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环.为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引从0开始).......
  • 【LeetCode2118. 建立方程】 group_concat指定分隔符,指定排序顺序
    目录题目地址题目描述代码题目地址https://leetcode.cn/problems/build-the-equation/description/题目描述Example2:输入:Terms表:+-------+--------+|power|factor|+-------+--------+|4|-4||2|1||1|-1|+-------+---......
  • 【LeetCode1225. 报告系统状态的连续日期】MySQL使用lag,lead得到连续段的:开始标志,结束
    目录题目地址题目描述代码题目地址https://leetcode.cn/problems/report-contiguous-dates/description/题目描述Asystemisrunningonetaskeveryday.Everytaskisindependentoftheprevioustasks.Thetaskscanfailorsucceed.Writeasolution toreportth......
  • 【LeetCode173. 最多连胜的次数】MySQL用户变量编程解法
    目录题目地址题目描述代码题目地址https://leetcode.cn/problems/longest-winning-streak/description/题目描述选手的 连胜数是指连续获胜的次数,且没有被平局或输球中断。编写解决方案来计算每个参赛选手最多的连胜数。结果可以以任何顺序返回。代码WITHt1AS(......
  • 【LeetCode1454. 活跃用户】MySQL 用户自定义变量,面向过程编程解决"连续天数"的问题
    目录题目地址题目描述代码题目地址https://leetcode.cn/problems/active-users/description/题目描述活跃用户是指那些至少连续 5天登录账户的用户。编写解决方案, 找到活跃用户的id和name。返回的结果表按照id排序 。代码注意需要处理,同一天多次登录的情形......
  • leetcode刷题日记
    unordered_set散列哈希表:C++STLunordered_set容器完全攻略(biancheng.net)unordered_map:详细介绍C++STL:unordered_map-朤尧-博客园(cnblogs.com)DAY1数组217.存在重复元素难度简单629给你一个整数数组nums。如果任一值在数组中出现至少两次,返回true;如果数组......
  • Leetcode 160. 链表相交(Intersection of two linked lists lcci)
    题目链接给定两个单链表的头节点headA和headB,请找出并返回两个单链表相交的起始节点.如果两个链表没有交点,返回null.图示两个链表在节点c1开始相交,题目数据保证整个链式结构中不存在环.示例1:输入:intersectVal=8,listA=[4,1,8,4,5],listB=[5,0,1,8,4,5],sk......