題目 : 2022q1 第 1 週測驗題
Leetcode的第一題。給你一個數列和target,求出哪兩個index相加的合為target,返回這兩個index。其中題目說答案只有一個。
因為C++ 內建map所以先用 C++驗證一次。
走訪這個數列的同時,在i的時候往前看(0 ~ i - 1)是否有target - nums[i],如果有就返回這兩個的index。
time complexity為
因為hashmap取值為
可是C裡面沒有hash map,所以必須自己實作一個。
struct的定義在include/linux/types.h
和list一樣操作都定義在include/linux/list.h
和list不太一樣的是,hlist_head為singly linked list。list_head和hlist_node為double linked list。
所以要取得tail的time complexity為O(N)。我覺得使用的時候盡量在node數量少的應用上。或是盡量不要對back做操作。像queue的實作應該就不適合,因為要同時存取front和back。
push_front | pop_front | push_back | pop_back |
---|---|---|---|
其中list_head的指標都是指向list_head。關於list_head的操作可以參考之前的筆記kernel study – list_head。這邊想專注在hlist。
使用hlist_node有兩種情況,
case1是hlist_node的前一個是hlist_head。
case2是hlist_node的前一個也是hlist_node。
如果像list_head一樣使用以下的code,會無法滿足case1,因為case1是指向不同的struct。
反過來如果使用以下的code,則會無法滿足case2,因為struct不一樣。
因為pprev只是為了指到前一個的next,不管前一個是hlist_node或是hlist_head,裡面的next或是first都是指向sturct hlist_node。所以把pprev宣告成,struct hlist_node **prev就可以解決這個問題。
參考jserv老師的程式碼
linux/include/hash.h
計算hash值。把val乘上GOLDEN_RATIO_32然後取前面MSB長度為bits來當hash值。
This hash multiplies the input by a large odd number and takes the high bits. Since multiplication propagates changes to the most significant end only, it is essential that the high bits of the product be used for the hash value.
程式碼所呈現的hashmap架構圖如下:
當key計算出hash之後就去map->ht[]找出對應的hlist_head,然後再traverse整個hlist找出一樣的key值。
第一種情況first後面沒node。則直接把new node加到h->first之後。
第二種情況first後面有node,則把new node加到h->first和first中間。
linux2022