【DW組隊學習—LeetCode】day12
146. LRU 快取機制
運用你所掌握的資料結構,設計和實現一個 LRU (最近最少使用) 快取機制 。
實現 LRUCache 類:
- LRUCache(int capacity) 以正整數作為容量 capacity 初始化 LRU 快取
- int get(int key)如果關鍵字 key 存在於快取中,則返回關鍵字的值,否則返回 -1 。
- void put(int key, int value)如果關鍵字已經存在,則變更其資料值;如果關鍵字不存在,則插入該組「關鍵字-值」。當快取容量達到上限時,它應該在寫入新資料之前刪除最久未使用的資料值,從而為新的資料值留出空間。
進階: 你是否可以在 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 <= 3000
- 0 <= value <= 104
- 最多呼叫 3 * 104次 get 和 put
需要注意的是當快取不夠時,最先被刪除的是最久未被使用的點
嘗試思路1:列表
根據指定長度,若列表不夠長,則向裡面新增,若夠長,則進行更替或者更新
更替是刪除最前面的元素,更新是刪除原先的元素,均在列表末尾加入新元素
程式碼:
class LRUCache:
def __init__(self, capacity: int):
self.l = []
self.capacity = capacity
def get(self, key: int) -> int:
for i in range(len(self.l)):
if key in self.l[i]:
return self.l[i][1]
return -1
def put(self, key: int, value: int) -> None:
for i in range(len(self.l)):
if self.l[i][0] == key:#key已存在
self.l.remove(self.l[i])
self.l.append([key, value])
return
if len(self.l) >= self.capacity:#key不存在
self.l.remove(self.l[0])
self.l.append([key, value])
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
【錯誤】測試算例出錯
雖然用的不是什麼有技術含量的方法,看題解用的是雜湊表,但個人覺得這個例項確實覺得在答案上有一定歧義。題目中說當快取滿時刪除最久未使用的資料值,按照排入循序,最先刪除的應該是[1,1],但答案中先刪除的是[2,2],感覺題目描述還是有些不夠嚴謹。也可能是我個人理解有誤
148. 排序連結串列
給你連結串列的頭結點 head ,請將其按 升序 排列並返回 排序後的連結串列 。
進階: 你可以在 O(n log n) 時間複雜度和常數級空間複雜度下,對連結串列進行排序嗎?
【示例 1】
輸入:head = [4,2,1,3] 輸出:[1,2,3,4]
【示例 2】
輸入:head = [-1,5,3,4,0] 輸出:[-1,0,3,4,5]
【示例 3】輸入:head = [] 輸出:[]
提示:
- 連結串列中節點的數目在範圍 [0, 5 * 104] 內
- -10^5 <= Node.val <= 10^5
嘗試思路:暴力法
直接將連結串列中所有資料提取出來,排序,然後寫新的連結串列
程式碼:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def sortList(self, head: ListNode) -> ListNode:
l = []
node = ListNode(0, None)
result = node
while head:
l.append(head.val)
head = head.next
l.sort()
for i in l:
node.next = ListNode(i, None)
node = node.next
return result.next
155. 最小棧
設計一個支援 push ,pop ,top 操作,並能在常數時間內檢索到最小元素的棧。
- push(x) —— 將元素 x 推入棧中。
- pop() —— 刪除棧頂的元素。
- top() —— 獲取棧頂元素。
- getMin() —— 檢索棧中的最小元素。
【示例】輸入: [“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”]
[[],[-2],[0],[-3],[],[],[],[]]
輸出: [null,null,null,null,-3,null,0,-2]
解釋:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
提示:
- pop、top 和 getMin 操作總是在 非空棧 上呼叫。
嘗試思路:用列表實現
增:append(number)
刪:del l[index]
取頂:l[-1]
最小:min(l)
程式碼:
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.s = []
def push(self, x: int) -> None:
self.s.append(x)
def pop(self) -> None:
del self.s[-1]
def top(self) -> int:
return self.s[-1]
def getMin(self) -> int:
return min(self.s)
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
【注】列表中幾種刪除元素方法及其區別:
- remove: 刪除單個元素,刪除首個符合條件的元素,按值刪除
- pop: 刪除單個或多個元素,按位刪除(根據索引刪除),刪除時會返回被刪除的元素
- del:它是根據索引(元素所在位置)來刪除
一開始編寫時用了remove所以一直不對,後來改用del才正確