有關(guān)鏈表的LeetCode做題筆記合集,Python實(shí)現(xiàn)
鏈表定義
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
24. 兩兩交換鏈表中的節(jié)點(diǎn) Swap Nodes in Pairs
記錄當(dāng)前節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)中剩,當(dāng)當(dāng)前節(jié)點(diǎn)和下一節(jié)點(diǎn)都存在時(shí)构灸,三元交換三個(gè)節(jié)點(diǎn)的next指針
返回交換完后的首節(jié)點(diǎn)
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
pre, pre.next = self, head
while pre.next and pre.next.next:
l = pre.next
r = l.next
pre.next, l.next, r.next = r, r.next, l
pre = l
return self.next
看到好多小伙伴在問(wèn)耍缴,我來(lái)嘗試解釋一下“鏈表交換相鄰元素”中 self 是怎么回事渐苏。
1.首先看到最后 return self.next 技健,可以看到作者是想把 self 當(dāng)做鏈表的頭指針使用的(注意:頭指針 pHead 與傳入的參數(shù) head 是不同的,head 是第一個(gè)結(jié)點(diǎn)浪汪,而 pHead.next == next )巴柿。用頭指針有什么好處呢?因?yàn)槲覀冏岊^指針的 next 域(pHead.next)永遠(yuǎn)指向第一個(gè)結(jié)點(diǎn)死遭,就是避免最后返回的時(shí)候找不到第一個(gè)結(jié)點(diǎn)了广恢。
2.那么作者為什么可以 pre, pre.next = self, head 這樣寫(xiě)呢?因?yàn)?self 是這個(gè)類的一個(gè)對(duì)象呀潭,所以在類定義的時(shí)候可以在任何地方钉迷,給 self 增加新的屬性。相信大家都知道在 init(self, attr) 里面可以定義通過(guò) self.myattr = attr 來(lái)定義一個(gè) myattr 屬性蜗侈。其實(shí)這個(gè)語(yǔ)句寫(xiě)在任意一個(gè)類的方法里都可以篷牌,所以在原文 swapPairs() 里面當(dāng)然也可以定義新的屬性睡蟋。所以這行代碼應(yīng)該理解為踏幻,pre 指向 self(雖然 self 不是一個(gè) ListNode 類型的對(duì)象,但它只要有一個(gè) next 就可以了)戳杀,同時(shí)為 pre(同時(shí)也是為 self该面,它們是一樣的現(xiàn)在)增加一個(gè) next 屬性,這個(gè) next 屬性指向第一個(gè)結(jié)點(diǎn) head信卡。
3.明白上面之后隔缀,這里就好辦了。在第一次 while 循環(huán)的時(shí)候傍菇,pre.next 被賦值為 b(也就是原來(lái)第二個(gè)結(jié)點(diǎn)猾瘸,轉(zhuǎn)換為變成了第一個(gè),也就成為了新鏈表的第一個(gè)結(jié)點(diǎn)。如果原來(lái)是[1,2,3,4]牵触,那么現(xiàn)在就是[2,1,3,4]淮悼,這個(gè) self.next 就是指向 2 這個(gè)結(jié)點(diǎn))。所以最后只要返回 self.next 就得到了答案揽思。
其實(shí)換個(gè)寫(xiě)法大家就好理解很多了:
pHead = ListNode(None)
pre, pre.next = pHead, head
也就是說(shuō)不用 self 也可以袜腥,只是原作者秀了一把小技巧而已。