contributed by < BensonYang1999
>
map_t
包含 bits
及 ht
,bits儲存hash table的大小( 1<<bits
),ht
為指向 hlist_head
的指標hlist_head
中只有一個指標 first
,指向 hlist_node
hlist_node
包含 pprev
及 next
, pprev
指向前一個node, next
指向後一個node;這裡比較特殊的地方 pprev
是用指標的指標,可以快速修改節點的連結。hash_key
包含 key, data, node
第一次使用 graphviz
,對 arrow 的調整還不熟悉,會發生edge與node邊框重疊的問題,不確定要怎麼解決。
注意書寫規範:中英文間用一個半形空白字元區隔。
不要急著說「第一次使用」,你很快會接觸一堆工具,理工人說話要精準且資訊量充足。
twoSum流程
10<<bits
map_get
測試是否有匹配的數值,若匹配成功回傳正確的組合function說明
map_init
目的:初始化map
,建立適當大小的hash table
map_t *map = malloc(sizeof(map_t));
if (!map)
return NULL;
map->bits = bits;
map->ht = malloc(sizeof(struct hlist_head) * MAP_HASH_SIZE(map->bits));
if (map->ht) {
for (int i = 0; i < MAP_HASH_SIZE(map->bits); i++)
(map->ht)[i].first = NULL;
} else {
free(map);
map = NULL;
}
return map;
find_key
目的:尋找key
是否存在在hash table中
先找到符合的head
後,造訪其中的所有node
,尋找相同key
的node
map_get
目地:利用find_key
找到符合的節點後,回傳其原始數值的陣列代碼。
map_add
目地:將原始數值利用hash轉換後,存入hash table,並紀錄陣列代碼。
詳細步驟:
n->next = first;
(12)n->pprev = &h->first;
(16)
void map_add(map_t *map, int key, void *data)
{
struct hash_key *kn = find_key(map, key);
if (kn)
return;
kn = malloc(sizeof(struct hash_key));
kn->key = key, kn->data = data;
struct hlist_head *h = &map->ht[hash(key, map->bits)];
struct hlist_node *n = &kn->node, *first = h->first;
n->next = first;
if (first)
first->pprev = &n->next;
h->first = n;
n->pprev = &h->first;
}
map_deinit
目的:把整個map中所有的 map, hash_key, node
清空
GOLDEN_RATIO_PRIME
,探討其實作考量思路:兩個判斷式都須考慮下一個節點是否存在
以及此節點與下一個節點是否擁有相同數值
,因此適當的程式碼為head->next && head->val == head->next->val
struct ListNode *deleteDuplicates(struct ListNode *head)
{
if (!head)
return NULL;
if (head->next && head->val == head->next->val) {
/* Remove all duplicate numbers */
while (head->next && head->val == head->next->val)
head = head->next;
return deleteDuplicates(head->next);
}
head->next = deleteDuplicates(head->next);
return head;
}
node
指向head
,利用判斷式確認是否有相同的值,當相同時將當前節的next
接到next->next
,代表忽略掉下一個節點,當不同時則直接將指標到下一個點
struct ListNode *deleteDuplicates(struct ListNode *head)
{
if (!head)
return NULL;
struct ListNode *node = head;
while (node->next) {
if (node->val == node->next->val) {
node->next = node->next->next;
}
else {
node = node->next;
}
}
return head;
}
node
及指標的指標dnode
,透過迴圈將所有重複的數字跳過,並利用dnode
把list接到下一個數字
struct ListNode *deleteDuplicates(struct ListNode *head)
{
if (!head)
return NULL;
struct ListNode *node = head, **dnode = &head;
while (node) {
if (node->next && node->val == node->next->val) {
while (node->next && node->val == node->next->val)
node = node->next;
*dnode = node->next; // 將dnode指向的指標(一開始為head)指向的下一個(不重複)的節點
node = node->next;
}
else {
dnode = &((*dnode)->next); // 將dnode指向下一個節點
node = node->next;
}
}
return head;
}