整体思路是:
使用双向链表数据结构来存储 LRU,结构如下:
typedef struct LRU_LIST_NODE { int key, value; struct LRU_LIST_NODE *prev, *next; } LRU_LIST_NODE_t;typedef struct { LRU_LIST_NODE_t *head; /* point to the oldest node */ LRU_LIST_NODE_t *tail; /* point to the latest node */ int node_cnt; /* node count */ int max_node_num; /* k */ } LRU_LIST;head 的 next 指针指向 oldest 节点,即每次淘汰的时候,淘汰 head->next;
tail 的 prev 指针指向 latest 节点,即每次更新操作后,将更新的节点放到 tail->prev分别定义如下的 API:
void LRU_INIT(LRU_LIST *list, int k); /* 初始化 cache list */ LRU_LIST_NODE_t* LRU_SEARCH(LRU_LIST *list, int key); /* 查找 key 对应的 ndoe */ void LRU_UPDATE(LRU_LIST *list, LRU_LIST_NODE_t *node); /* 更新 node 到最新 */ int LRU_SET(LRU_LIST* list, int key, int value); /* 插入 key, value */ int LRU_GET(LRU_LIST* list, int key); /* 获取 key 对应的 value */
下面是项目代码, 有些变量在牛客网下面如果编译不通过,修改下即可
typedef struct LRU_LIST_NODE {
int key, value;
struct LRU_LIST_NODE *prev, *next;
} LRU_LIST_NODE_t;
typedef struct {
LRU_LIST_NODE_t *head; /* point the oldest node */
LRU_LIST_NODE_t *tail; /* point the latest node */
int node_cnt; /* node count */
int max_node_num; /* k */
} LRU_LIST;
LRU_LIST_NODE_t* LRU_SEARCH(LRU_LIST *list, int key) {
LRU_LIST_NODE_t *h = list->head->next;
while (h != list->tail) {
if (h->key == key) {
return h;
}
h = h->next;
}
return NULL;
}
/* adjust the node to the tail */
void LRU_UPDATE(LRU_LIST *list, LRU_LIST_NODE_t *node) {
if (list->node_cnt == 1) {
return;
}
/* remove this node first */
LRU_LIST_NODE_t *p = node->prev;
p->next = node->next;
node->next->prev = p;
/* then, insert to the tail */
LRU_LIST_NODE_t *ori_latest_node = list->tail->prev;
ori_latest_node->next = node;
node->prev = ori_latest_node;
node->next = list->tail;
list->tail->prev = node;
}
int LRU_SET(LRU_LIST* list, int key, int value) {
LRU_LIST_NODE_t *node = LRU_SEARCH(list, key);
if (node != NULL) {
node->value = value;
/* update */
LRU_UPDATE(list, node);
return 0;
}
/* insert */
if (list->node_cnt == list->max_node_num) {
/* delete the oldest if list is full */
LRU_LIST_NODE_t *oldest_node = list->head->next;
list->head->next = oldest_node->next;
oldest_node->next->prev = list->head;
free(oldest_node);
}
LRU_LIST_NODE_t *new_node = (LRU_LIST_NODE_t *)malloc(sizeof(LRU_LIST_NODE_t));
if (new_node == NULL) {
return -1;
}
new_node->key = key;
new_node->value = value;
/* insert to the latest */
LRU_LIST_NODE_t *ori_latest = list->tail->prev;
ori_latest->next = new_node;
list->tail->prev = new_node;
new_node->next = list->tail;
new_node->prev = ori_latest;
/* 坑 1 */
if (list->node_cnt != list->max_node_num) {
list->node_cnt++;
}
return 0;
}
int LRU_GET(LRU_LIST* list, int key) {
LRU_LIST_NODE_t *node = LRU_SEARCH(list, key);
if (node == NULL) {
return -1;
}
LRU_UPDATE(list, node);
return node->value;
}
void LRU_INIT(LRU_LIST *list, int k) {
list->max_node_num = k;
list->head = (LRU_LIST_NODE_t *)malloc(sizeof(LRU_LIST_NODE_t));
list->tail = (LRU_LIST_NODE_t *) malloc (sizeof(LRU_LIST_NODE_t));
list->head ->next = list->tail;
list->head->prev = NULL;
list->tail->next = NULL;
list->tail->prev = list->head;
list->node_cnt = 0;
}
/* parse operator */
int judgeOps(int *operator, int operatorCplen) {
if (operator[0] == 1 && operatorCplen == 3) {
return 0;
}
if (operator[0] == 2 && operatorCplen == 2) {
return 0;
}
return -1;
}
LRU_LIST list;
int LRU_RES[102400];
int* LRU(int** operators, int operatorsRowLen, int* operatorsColLen, int k, int* returnSize) {
// write code here
if (list.max_node_num != k) {
LRU_INIT(&list, k);
}
*returnSize = 0;
for (int i = 0; i < operatorsRowLen; i++) {
int *ope = operators[i];
int opeLen = operatorsColLen[i];
if (judgeOps(ope, opeLen) != 0) {
return LRU_RES;
}
if (ope[0] == 1) {
LRU_SET(&list, ope[1], ope[2]);
} else {
LRU_RES[*returnSize] = LRU_GET(&list, ope[1]);
(*returnSize)++;
}
}
return LRU_RES;
}
京公网安备 11010502036488号