【Leetcode hot 100】146.LRU緩存

問題鏈接

146.LRU緩存

問題描述

請你設計并實現一個滿足 LRU (最近最少使用) 緩存 約束的數據結構。
實現 LRUCache 類:

  • LRUCache(int capacity)正整數 作為容量 capacity 初始化 LRU 緩存
  • int get(int key) 如果關鍵字 key 存在于緩存中,則返回關鍵字的值,否則返回 -1
  • void put(int key, int value) 如果關鍵字 key 已經存在,則變更其數據值 value ;如果不存在,則向緩存中插入該組 key-value 。如果插入操作導致關鍵字數量超過 capacity ,則應該 逐出 最久未使用的關鍵字。

函數 getput 必須以 O(1) 的平均時間復雜度運行。

示例:

輸入
[“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
輸出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解釋
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 緩存是 {1=1}
lRUCache.put(2, 2); // 緩存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 該操作會使得關鍵字 2 作廢,緩存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 該操作會使得關鍵字 1 作廢,緩存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4

提示:

  • 1 <= capacity <= 3000
  • 0 <= key <= 10000
  • 0 <= value <= 10^5
  • 最多調用 2 * 10^5getput

問題解答

要解決LRU(最近最少使用)緩存問題,我們需要設計一個數據結構,支持在O(1)平均時間復雜度內完成getput操作。核心思路是結合哈希表(快速查找)和雙向鏈表(維護使用順序)。

解題思路

  1. 數據結構選擇

    • 哈希表(HashMap):存儲鍵到雙向鏈表節點的映射,實現O(1)時間復雜度的查找。
    • 雙向鏈表:維護節點的使用順序,最近使用的節點放在鏈表頭部,最久未使用的節點放在尾部,支持O(1)時間復雜度的插入、刪除和移動操作。
    • 虛擬頭節點和虛擬尾節點:簡化邊界處理(如插入第一個節點或刪除最后一個節點時無需判斷null)。
  2. 核心操作

    • get(key):若鍵存在,將對應節點移到鏈表頭部(標記為最近使用)并返回值;否則返回-1。
    • put(key, value):若鍵存在,更新值并將節點移到頭部;若鍵不存在,創建新節點插入頭部,若容量超限,刪除鏈表尾部節點(最久未使用)并從哈希表中移除對應鍵。

代碼實現

import java.util.HashMap;
import java.util.Map;class LRUCache {// 雙向鏈表節點static class Node {int key;int value;Node prev;Node next;public Node(int key, int value) {this.key = key;this.value = value;}}private final Map<Integer, Node> cache; // 哈希表:key -> 節點private final Node head; // 虛擬頭節點private final Node tail; // 虛擬尾節點private final int capacity; // 緩存容量public LRUCache(int capacity) {this.capacity = capacity;cache = new HashMap<>(capacity);// 初始化虛擬節點并連接head = new Node(-1, -1);tail = new Node(-1, -1);head.next = tail;tail.prev = head;}public int get(int key) {if (!cache.containsKey(key)) {return -1; // 鍵不存在,返回-1}Node node = cache.get(key);moveToHead(node); // 訪問后移到頭部(最近使用)return node.value;}public void put(int key, int value) {if (cache.containsKey(key)) {// 鍵存在,更新值并移到頭部Node node = cache.get(key);node.value = value;moveToHead(node);} else {// 鍵不存在,創建新節點Node newNode = new Node(key, value);cache.put(key, newNode);addToHead(newNode); // 插入頭部// 若容量超限,刪除尾部節點(最久未使用)if (cache.size() > capacity) {Node tailNode = removeTail();cache.remove(tailNode.key);}}}// 將節點移到頭部(先刪除再插入頭部)private void moveToHead(Node node) {removeNode(node);addToHead(node);}// 從鏈表中移除節點private void removeNode(Node node) {node.prev.next = node.next;node.next.prev = node.prev;}// 將節點插入到頭部(虛擬頭節點之后)private void addToHead(Node node) {node.next = head.next;node.prev = head;head.next.prev = node;head.next = node;}// 移除尾部節點(虛擬尾節點之前的節點)并返回private Node removeTail() {Node res = tail.prev;removeNode(res);return res;}
}

復雜度分析

  • 時間復雜度getput操作均為O(1)。哈希表保證了鍵的查找為O(1),雙向鏈表保證了節點的插入、刪除和移動為O(1)。
  • 空間復雜度:O(capacity),最多存儲capacity個鍵值對。

該實現通過哈希表和雙向鏈表的結合,高效滿足了LRU緩存的約束,適用于需要頻繁訪問且對性能要求較高的場景。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95967.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95967.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95967.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL超大數據量查詢與刪除優化

引言 在處理TB級數據時&#xff0c;傳統SQL操作可能導致性能崩潰。本文揭示MySQL超大數據量場景下的核心優化策略&#xff0c;通過生產環境案例展示如何將億級數據刪除耗時從8小時壓縮至8分鐘&#xff0c;并附完整監控方案與容災措施。 深度剖析海量數據操作痛點 1. 傳統刪除操…

【內存管理】常用的頁表映射函數

1、pgd_addr_end 根據當前虛擬地址 addr 和目標結束地址 end&#xff0c;計算當前 PGD 項 能夠覆蓋的最大虛擬地址范圍的結束地址 next。 如果 addr 和 end 跨越多個 PGD 項&#xff08;即 end 超出當前 PGD 項的地址范圍&#xff09;&#xff0c;則返回當前 PGD 項的地址邊界。…

XR數字融合工作站賦能新能源汽車專業建設的創新路徑

XR數字融合工作站作為集PC、VR、MR技術于一體的軟硬件集成平臺&#xff0c;憑借其多維交互、虛實融合、智能管理等特性&#xff0c;為新能源汽車專業的教學改革與創新提供了全新解決方案。一、教學場景革新&#xff1a;構建沉浸式、互動化學習環境XR數字融合工作站通過多形態拼…

C語言通用鏈表終章:優雅的收尾 - 清空與銷毀

各類資料學習下載合集 ?https://pan.quark.cn/s/8c91ccb5a474? 經過前面的學習,我們已經從零構建了一個功能強大的通用鏈表,它能自如地進行節點的插入和刪除。我們的“數據火車”已經可以馳騁在內存的世界里。然而,旅途終有終點,當火車完成任務后,如何安全、徹底地讓…

MATLAB R2025a安裝配置及使用教程(超詳細保姆級教程)

文章目錄前言什么是MATLAB&#xff1f;了解這款數據分析利器matlab安裝前準備工作MATLAB R2025a下載完整MATLAB R2025a安裝步驟MATLAB進階應用技巧前言 全網最新最全的MATLAB R2025a安裝教程來了&#xff01;2025年版本完整圖文指南&#xff0c;包含軟件下載、詳細安裝、密鑰激…

在Mybatis plus中如何使用自定義Sql

在演示UpdateWrapper的案例中&#xff0c;我們在代碼中編寫了更新的SQL語句&#xff1a;Test void testUpadateWrapper(){List<Long> ids List.of(1L,2L,4L);//生成SQLUpadateWrapper<User> wrapper new UpdateWrapper<User> ().setSql("balance balan…

Deepoc科技之暖:智能助盲設備如何為視障家人點亮生活

作為一名視障人士的家屬&#xff0c;我們或許都經歷過這樣的時刻&#xff1a;看著親人在書架前摸索&#xff0c;卻無法獨自獲取文字信息&#xff1b;擔心他們外出時遇到障礙物或交通危險&#xff1b;心疼他們因找不到日常物品而不得不一次次求助。這些細微的日常困境&#xff0…

大模型食材識別技術革新:AI重構精準營養管理

隨著健康意識的提升&#xff0c;飲食管理需求激增&#xff0c;但傳統手動記錄易出錯、效率低。大模型食材識別技術的突破&#xff0c;讓AI通過多模態輸入精準識別食材種類與重量&#xff0c;結合營養數據庫&#xff0c;系統可快速生成營養報告&#xff0c;實現從“經驗驅動”到…

使用 Altair RapidMiner 將機器學習引入您的 Mendix 應用程序

Altair RapidMiner 使機器學習更加容易&#xff1a;無論您喜歡使用 Python 編碼&#xff0c;還是在 Workflow Studio 中進行可視化工作&#xff0c;Altair AI Cloud 都能為團隊提供快速構建和部署 ML 模型的工具。 將機器學習與 Mendix 集成很簡單&#xff1a;通過 Mendix 的低…

EasyExcel:快速讀寫Excel的工具類

EasyExcel&#xff1a;快速讀寫Excel的工具類 項目介紹 ?EasyExcel是一個基于Java的、快速、簡潔、解決大文件內存溢出的Excel處理工具。 他能讓你在不用考慮性能、內存的等因素的情況下&#xff0c;快速完成Excel的讀、寫等功能。 pom地址 ? <!--exel--> <depe…

WSL Ubuntu Docker 代理自動配置教程

WSL Ubuntu Docker 代理自動配置教程 WSL Ubuntu Docker 代理自動配置教程 背景說明 在 WSL2 環境下使用 Docker 時&#xff0c;由于網絡環境限制&#xff0c;經常需要通過 Windows 主機上的代理來訪問 Docker Hub。但每次 Windows 重啟后&#xff0c;WSL 獲取到的主機 IP 地址…

踩坑實錄:Django繼承AbstractUser時遇到的related_name沖突及解決方案

一、問題現象分析 咱們在用Django開發時&#xff0c;有時候需要擴展用戶模型&#xff0c;就會去繼承AbstractUser。但這么做的時候&#xff0c;要是沒處理好groups和user_permissions這兩個多對多字段的反向查詢名稱&#xff0c;就會遇到這樣的報錯&#xff1a;主要就是這種錯誤…

push pop 和 present dismiss

push/pop 和 present/dismiss 文章目錄push/pop 和 present/dismiss前言push / poppresent普通的present多層present多層present后的父子關系問題多層彈出會遇到的問題showViewController 和 showDetailViewControllershowViewControllershowDetailViewControllerdismiss模態化…

服務器異常負載排查手冊 · 隱蔽進程篇

適用范圍 適用于 Linux 3.10 生產環境&#xff0c;發現 load 高但用戶態 CPU 接近 0 % 的場景。1. 現場凍結目標&#xff1a;在 rootkit 干預前保存易失數據。#!/bin/bash # freeze.sh TS$(date %s) mkdir -p /srv/ir/${TS} cd /srv/ir/${TS}# 1.1 進程樹&#xff08;busybox 靜…

2024理想算法崗筆試筆記

要理解指令微調&#xff08;Instruction Tuning&#xff09;&#xff0c;需要先將其置于大語言模型&#xff08;LLM&#xff09;的訓練框架中 —— 它并非模型訓練的起點&#xff0c;而是針對 “讓模型更懂人類需求” 的關鍵優化步驟。簡單來說&#xff0c;指令微調是通過讓模型…

Oracle 11g離線安裝依賴包完整解決方案

本文還有配套的精品資源&#xff0c;點擊獲取 簡介&#xff1a;Oracle 11g是一款廣泛使用的關系型數據庫管理系統&#xff0c;在離線環境下安裝時需依賴多個系統庫和工具。本“oracle11g依賴包”壓縮文件包含了在CentOS 7.7上安裝Oracle 11g可能缺失的關鍵依賴RPM包&#xf…

VBA數據結構選型:效率差5倍的生死抉擇

VBA性能生死局&#xff1a;Dictionary與Collection效率差5倍&#xff01;90%開發者用反血虧“你以為Collection是VBA的‘輕量級選手’&#xff1f;大錯特錯&#xff01;實測數據顯示&#xff1a;在10萬級數據循環中&#xff0c;Dictionary的查詢速度比Collection快5倍&#xff…

電機控制(四)-級聯PID控制器與參數整定(MATLABSimulink)

PID算法 普通PID&#xff08;Proportional-Integral-Derivative&#xff09; 通過比例&#xff08;P&#xff09;、積分&#xff08;I&#xff09;和微分&#xff08;D&#xff09;三項來進行控制 比例項&#xff08;P&#xff09;&#xff1a;根據當前誤差&#xff08;目標值…

數據結構深度解析:二叉樹的基本原理

在數據結構體系中&#xff0c;樹是一種重要的非線性層次結構&#xff0c;它通過 “節點” 與 “邊” 的連接關系&#xff0c;模擬了現實世界中樹的分支結構&#xff0c;能夠高效地解決數據的查找、插入、刪除等問題。而二叉樹作為樹結構中最簡單、應用最廣泛的類型&#xff0c;…

【React】Ant Design 5.x 實現tabs圓角及反圓角效果

需要實現的效果實現思路 利用tab頁的before和after屬性&#xff0c;添加tab頁前后的圓弧屬性&#xff0c;同時使用tab頁的shadow陰影填充右下角的圓弧空缺部分。<TabsonChange{onChange}type"card"items{getTabItems()}/>.ant-tabs-nav{margin: 0;.ant-tabs-na…