# 初始化頭節點 head = ListNode(nums[0][0]) current = head node_dict[0] = head random_dict[head] = nums[0][1]
# 迭代列表中的其餘元素並創建鏈表 for index, num inenumerate(nums[1:], start=1): current.next = ListNode(num[0]) current = current.next node_dict[index] = current random_dict[current] = num[1]
# 處理 random for node in node_dict.values(): random_index = random_dict[node] node.random = node_dict.get(random_index)
return head
defprint_node_list(node): while node: print(f"(val: {node.val}, random.val: {node.random.val if node.random elseNone}) -> ", end="") node = node.next print("None")
# 1. 先做好所有node的dict (key: index, value: node) index = 0 dummy = ListNode(-1) current = dummy while head: current.next = ListNode(head.val) node_dict.__setitem__(index, current.next) # 換下一個階段 head = head.next current = current.next index += 1
new_head = dummy.next dummy.next = None
# 2. 開始幫 new_head 塞 random based on `random_index_dict` current = new_head index = 0 while current: random_index_of_cur_index = random_index_dict.get(index) random_node = node_dict.get(random_index_of_cur_index) current.random = random_node current = current.next index += 1
return new_head
2.2 使用 HashTable
這個做法也是建立 HashTable 但是沒有像我這麼笨,他是直接把 old_node 當作 key,new_node 當作 value。簡直天才!因為這樣不管是串 next 還是串 random 都只要拿 old_node 去找,就可以找到 new_node,然後開始串。
# 1. 做好 新舊對應的 dict cur = head while cur: old_to_new[cur] = ListNode(cur.val) cur = cur.next
cur = head while cur: # 2. 因為已經有一個全部的dict 所以可以容易地將 next 跟 random 串起來 old_to_new[cur].next = old_to_new.get(cur.next) old_to_new[cur].random = old_to_new.get(cur.random) cur = cur.next
return old_to_new[head]
3 總結
這題我是有想出來的,並且通過測試。我也想到要使用HashTable,但是我卻沒想到要使用 old_node 來當作 key,new_node 來當作 value,這樣就可以在找 random 的時候,直接找到 new_node 就可以了。這個解法真的很巧妙,超級厲害!