https://labuladong.online/algo/data-structure-basic/linkedlist-basic/
今天是學習的第 18 天,主要學習了用陣列加強哈希表(ArrayHashMap):
randomKey()
API如果我們想在基於哈希表的 API 之上,新增一個 randomKey()
API,可以在 O(1) 的時間複雜度內返回一個隨機的鍵,這件事並沒有那麼地容易。
使用額外的陣列來儲存所有鍵,結合哈希表建立雙向映射:
arr
:按順序儲存所有鍵值對 key-value
節點map
:建立 key -> 陣列索引
的映射關係O(1) 刪除陣列元素
普通陣列刪除中間元素需要移動資料,時間複雜度是 O(n),解決方案:
class MyArrayHashMap {
constructor() {
this.map = new Map(); // key -> 陣列索引
this.arr = []; // 儲存所有 key-value 節點
}
put(key, val) {
if (this.containsKey(key)) {
// 修改現有值
let i = this.map.get(key);
this.arr[i].val = val;
} else {
// 新增:加到陣列尾部,建立映射
this.arr.push(new Node(key, val));
this.map.set(key, this.arr.length - 1);
}
}
remove(key) {
// 交換到尾部 -> 刪除尾部 -> 更新映射
let index = this.map.get(key);
let lastElement = this.arr[this.arr.length - 1];
this.arr[index] = lastElement;
this.map.set(lastElement.key, index);
this.arr.pop();
this.map.delete(key);
}
randomKey() {
let randomIndex = Math.floor(Math.random() * this.arr.length);
return this.arr[randomIndex].key;
}
}