Leetcode Datastruct
紀錄一些在Leetcode上關於Datastruct有去的題目
SkipList
Leetcode 1206
- 定義初始結構
- 這邊level為6主要是因為題目最大Node為
- level計算和推倒
static const int level = 6;
struct Node {
int val;
vector<Node*> next;
Node(int v) : val(v) {
next.resize(level, NULL);
}
}*head;
Skiplist() {
head = new Node(-1);
}
~Skiplist() {
auto p = head;
while(p != NULL) {
auto nextNode = p->next[0];
delete p;
p = nextNode;
}
}
- 最主要的輔助函數
- find函數會找到該層中小於target的最大節點
void find(int target,vector<Node*>&pre) {
auto p = head;
for(int i=level-1;i>=0;i--){
while(p->next[i] != NULL && p->next[i]->val < target)
p = p->next[i];
pre[i] = p; // 代表找到該層的最大節點為p
}
}
- insert函數
void add(int num) {
vector<Node*> pre(level);
find(num,pre); //找到該層小於num的最大節點
auto newNode = new Node(num);
for(int i=0;i<level;i++){
// 大節點插入右側
newNode->next[i] = pre[i]->next[i];
pre[i]->next[i] = newNode;
if(rand() % 2) break; // 每層level都有50%的機率插入level+1,假設沒中就直接退出
}
}
- search函數
bool search(int target) {
vector<Node*> pre(level);
find(target,pre);
auto p = pre[0]->next[0]; //第0層會存所有的node,因此只要確認到該層中有沒有該節點即可(透過find)
return p && p->val == target;
}
- erase函數
bool erase(int num) {
vector<Node*> pre(level);
find(num,pre);
auto p = pre[0]->next[0];
if (!p || p->val != num) return false;
for(int i=0; i < level && pre[i]->next[i] == p;i++) {
pre[i]->next[i] = p->next[i];
}
delete p;
return true;
}