原題鏈接:Reverse Linked List
這道題,我們用迭代的方法原地反轉(zhuǎn)單鏈表明刷,先上代碼:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
newHead = None
while head != None:
nextNode = head.next
head.next = newHead
newHead = head
head = nextNode
return newHead
我們采取的方法是這樣的婴栽,逐個(gè)反轉(zhuǎn)每一個(gè)指針,
舉個(gè)例子:
假設(shè)鏈表是這個(gè)樣子的:head->1->2->3->4->None
那么在第一步結(jié)束后辈末,鏈表應(yīng)該是這個(gè)樣子的:None<-head, 1->2->3->4->None
在第二步結(jié)束后愚争,鏈表是這個(gè)樣子的:None<-head<-1, 2->3->4->None
在第三步結(jié)束后,鏈表是這個(gè)樣子的:None<-head<-1<-2, 3->4->None
以此類推挤聘。
那么我們現(xiàn)在來(lái)看具體的代碼轰枝,以及嘗試?yán)斫膺@些代碼是如何做到上述的步驟的:
nextNode = head.next #1
head.next = newHead #2
newHead = head #3
head = nextNode #4
#1:這句代碼是用來(lái)保存革命的火種。
因?yàn)榧偃缥覀冎苯臃崔D(zhuǎn)了head.next
的指向组去,那么head.next
之前指向的內(nèi)容(即鏈表在head這個(gè)節(jié)點(diǎn)后面的部分)都會(huì)丟失了鞍陨。所以我們?cè)诜崔D(zhuǎn)第一個(gè)指針的指向之前,我們要保存一下它的值从隆。
#2:這句代碼就是反轉(zhuǎn)指針的操作诚撵。
這個(gè)newHead
就是用來(lái)裝前一個(gè)節(jié)點(diǎn)的變量(其實(shí)它是前一個(gè)節(jié)點(diǎn)的引用,不過(guò)不要在意這些細(xì)節(jié)键闺,我們主要是方便理解)寿烟,
比如說(shuō),當(dāng)我們反轉(zhuǎn)head->1
后辛燥,反轉(zhuǎn)結(jié)果為None<-head, 1
韧衣,此時(shí)newHead
就是None
盅藻;
當(dāng)我們反轉(zhuǎn)1->2
后,反轉(zhuǎn)結(jié)果為head<-1, 2
畅铭,此時(shí)newHead
就是head
氏淑。
#3:反轉(zhuǎn)指針之后,我們需要更新
newHead
的值硕噩,用于下一輪的反轉(zhuǎn)假残。
這里我們要思考一下,為什么用head
的值來(lái)更新newHead
呢炉擅?
答:因?yàn)檫@一輪的head
就是下一輪辉懒,指針?lè)崔D(zhuǎn)后要被指向的節(jié)點(diǎn),也就是newHead
谍失。
#4:這句代碼主要是配合#1的代碼眶俩。既然#1已經(jīng)保存了革命的火種,那在下一輪即將開始之前快鱼,我們當(dāng)然要將火種傳遞下去颠印。
這里我們還要思考一下,為什么要傳給head
而不是newHead
抹竹?
答:因?yàn)?code>head指向的是尚未被反轉(zhuǎn)的鏈表部分跋吆薄!而newHead
指向的是已被反轉(zhuǎn)的鏈表部分扒耘小钞楼!
總結(jié):
以上是用迭代方法原地反轉(zhuǎn)單鏈表,至于遞歸的方法等有時(shí)間再寫吧~~~