LeetCode - 146. LRU 캐 시 메커니즘
6726 단어 LeetCode
당신 이 파악 한 데이터 구 조 를 활용 하여 LRU (최근 최소 사용) 캐 시 체 제 를 설계 하고 실현 합 니 다.데이터 get 을 가 져 오고 데 이 터 를 기록 하 는 put 를 지원 해 야 합 니 다.
데이터 get (key) 가 져 오기 - 키 (key) 가 캐 시 에 존재 하면 키 의 값 (항상 정수) 을 가 져 옵 니 다. 그렇지 않 으 면 - 1 을 되 돌려 줍 니 다.데이터 put (key, value) 를 기록 합 니 다. 키 가 존재 하지 않 으 면 데이터 값 을 기록 합 니 다.캐 시 용량 이 상한 선 에 이 르 렀 을 때 새 데 이 터 를 쓰기 전에 최근 에 가장 적 게 사용 한 데이터 값 을 삭제 하여 새로운 데이터 값 에 공간 을 남 겨 야 합 니 다.
진급: 당신 은 O (1) 시간 복잡 도 내 에 이 두 가지 조작 을 완성 할 수 있 습 니까?
예시:
LRUCache cache = new LRUCache (2 / * 캐 시 용량 * /);
cache.put(1, 1); cache.put(2, 2); cache.get(1); // 1 cache. put (3, 3); /이 동작 은 키 2 를 cache. get (2) 로 폐기 합 니 다. /반환 - 1 (찾 을 수 없 음) cache. put (4, 4); /이 동작 은 키 1 을 cache. get (1) 로 폐기 합 니 다. /반환 - 1 (찾 을 수 없 음) cache. get (3); /3 cache. get (4); /돌아오다
문제 풀이 방향 - 양 방향 링크 + 해시 표: 양 방향 링크 와 해시 표 의 결합 을 사용 하면 O (1) 의 시간 복잡 도 에서 LRU 캐 시 체 제 를 완성 할 수 있 습 니 다.표 헤드 와 표 끝 이 있 는 더 블 링크 를 구축 하여 LRU 색인 표 로 하고 HashMap 을 데이터 시트 로 하여 모든 링크 노드 를 저장 하 며 추가 하거나 업데이트 하 는 노드 를 링크 헤드 에 두 고 HashMap 의 개수 가 용량 상한 선 에 도달 하면 링크 의 마지막 노드 를 삭제 합 니 다.데 이 터 를 가 져 올 때 HashMap 에서 대응 하 는 key 값 value 를 직접 가 져 오 면 됩 니 다.
문제 풀이 사고방식 - LinkedHashMap 사용: LinkedHashMap 은 Map 인터페이스의 해시 테이블 과 양 방향 체인 테이블 의 결합 으로 LRU 캐 시 메커니즘 을 실현 하기에 특히 적합 하 다.링크 드 HashMap 에 참조 가 있 는 구조 함수 가 있 습 니 다:
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
그 중:
LinkedHashMap 은 removeEldestEntry (Map. Entry eldest) 방법 도 제공 합 니 다. 이 방법 은 새로운 요 소 를 추가 할 때마다 가장 오래된 요 소 를 제거 할 수 있 습 니 다.방법 은 기본 값 을 false 로 되 돌려 줍 니 다. 오래된 요 소 를 제거 하지 않 습 니 다.반환 값 이 true 일 때 제거 기능 을 실현 할 수 있 습 니 다.방법 은 다음 과 같다.
protected boolean removeEldestEntry(Map.Entry eldest) {
return false;
}
따라서 LRU 캐 시 체 제 를 실현 하려 면 인삼 이 있 는 링크 드 HashMap 을 새로 만 들 고 Override 함수 removeEldestEntry 를 사용 하여 map. size > capacity 를 되 돌려 줍 니 다. 즉, 현재 map 의 용량 이 상한 선 을 설정 할 때 가장 오래된 요소 제거 기능 을 실현 합 니 다.자바 문제 풀이 에 서 는 두 가지 코드 구현 방식 을 제공 합 니 다. 하 나 는 클 라 스 를 새로 만 드 는 것 이 고, 또 하 나 는 정례 화 대상 일 때 override 입 니 다.
자바 문제 풀이 - 양 방향 링크 + 해시 표
import java.util.HashMap;
import java.util.Map;
class LRUCache {
//
class Node{
int key;
int value;
Node pre;
Node next;
public Node(int key, int value){
this.key = key;
this.value = value;
}
}
private int capacity;
private Node first;
private Node last;
private Map map;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>(capacity);
}
public int get(int key) {
Node node = map.get(key);
if(node==null) return -1;
movetoHead(node);
return node.value;
}
public void put(int key, int value) {
Node node = map.get(key);
if(node==null){
node = new Node(key, value);
// map capacity
//
if(map.size()==this.capacity)
removeLast();
addtoHead(node);
map.put(key, node);
}else{
node.value = value;
movetoHead(node);
}
}
//
public void movetoHead(Node node){
if(node==first)
return;
else if(node==last){
last.pre.next = null;
last = last.pre;
}else{
node.pre.next = node.next;
node.next.pre = node.pre;
}
node.pre = first.pre;
node.next = first;
first.pre = node;
first = node;
}
//
public void removeLast(){
map.remove(last.key);
Node prenode = last.pre;
if(prenode!=null)
prenode.next = null;
last = prenode;
}
//
public void addtoHead(Node node){
if(map.isEmpty()){
first = node;
last = node;
}else{
node.next = first;
first.pre = node;
first = node;
}
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
자바 문제 풀이 - LinkedHashMap - 1 사용
import java.util.LinkedHashMap;
import java.util.Map.Entry;
class LRULinkedHashMap extends LinkedHashMap{
//
private int capacity;
//
public LRULinkedHashMap(int capacity){
// accessOrder true, LRU ,
// 0.75 LinkedHashMap
super(capacity, 0.75f, true);
this.capacity = capacity;
}
// size capacity , ture,
// macos idea ,override command+o,
@Override
protected boolean removeEldestEntry(Entry eldest) {
return this.size() > this.capacity;
}
}
class LRUCache {
private LRULinkedHashMap LRUMap; //
public LRUCache(int capacity) {
this.LRUMap = new LRULinkedHashMap(capacity);
}
public int get(int key) {
Integer value = LRUMap.get(key);
if(value==null) return -1;
return value;
}
public void put(int key, int value) {
LRUMap.put(key, value);
}
}
자바 문제 풀이 - LinkedHashMap - 2 사용
import java.util.LinkedHashMap;
import java.util.Map.Entry;
class LRUCache {
private LinkedHashMap map;
private int capacity;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new LinkedHashMap(capacity, 0.75f, true){
@Override
protected boolean removeEldestEntry(Entry eldest) {
return this.size()> capacity;
}
};
}
public int get(int key) {
Integer value = this.map.get(key);
if(value==null) return -1;
return value;
}
public void put(int key, int value) {
this.map.put(key, value);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
python 문자열 입력으로 모든 유효한 IP 주소 생성(LeetCode 93번 문제)이 문제의 공식 난이도는 Medium으로 좋아요 1296, 반대 505, 통과율 35.4%를 눌렀다.각 항목의 지표로 말하자면 보기에는 약간 규범에 맞는 것 같지만, 실제로도 확실히 그렇다.이 문제의 해법과 의도는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.