206
https://leetcode-cn.com/problems/reverse-linked-list/
反轉一個單鏈表。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
進階:
你可以迭代或遞歸地反轉鏈表。你能否用兩種方法解決這道題?
我們使用兩種方式解決這個問題:
-
迭代
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
pre = head
ans = None
while pre != None:
nextTemp = pre.next
pre.next = ans
ans = pre
pre = nextTemp
return ans
思路:首先新建兩個變量pre和ans,然後遍歷鏈表,pre用來記錄當前遍歷的節點,ans作爲最後輸出的鏈表首先賦值變量None。每次遍歷鏈表的時候,將當前遍歷的節點指向ans,然後將該節點賦值給ans,pre記錄遍歷,最後輸出ans。
- 遞歸
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if head==None:
return head
if head.next == None:
return head
HEAD = self.reverseList(head.next)
head.next.next = head # head爲當前節點的前一個節點,也就是讓當前節點指向上一個節點
head.next = None #將當前節點的上一個節點指向None
return HEAD
思路:看圖即可
92
https://leetcode-cn.com/problems/reverse-linked-list-ii/
反轉從位置 m 到 n 的鏈表。請使用一趟掃描完成反轉。
說明:
1 ≤ m ≤ n ≤ 鏈表長度。
示例:
輸入: 1->2->3->4->5->NULL, m = 2, n = 4
輸出: 1->4->3->2->5->NULL
解析
對於鏈表的問題,根據以往的經驗一般都是要建一個dummy node,連上原鏈表的頭結點,這樣的話就算頭結點變動了,我們還可以通過dummy->next來獲得新鏈表的頭結點。這道題的要求是隻通過一次遍歷完成,就拿題目中的例子來說,變換的是2,3,4這三個點,我們需要找到第一個開始變換結點的前一個結點,只要讓pre向後走m-1步即可,爲啥要減1呢,因爲題目中是從1開始計數的,這裏只走了1步,就是結點1,用pre指向它。萬一是結點1開始變換的怎麼辦,這就是我們爲啥要用dummy結點了,pre也可以指向dummy結點。然後就要開始交換了,由於一次只能交換兩個結點,所以我們按如下的交換順序:
1 -> 2 -> 3 -> 4 -> 5 -> NULL
1 -> 3 -> 2 -> 4 -> 5 -> NULL
1 -> 4 -> 3 -> 2 -> 5 -> NULL
我們可以看出來,總共需要n-m步即可,第一步是將結點3放到結點1的後面,第二步將結點4放到結點1的後面。這是很有規律的操作,那麼我們就說一個就行了,比如剛開始,pre指向結點1,cur指向結點2,然後我們建立一個臨時的結點t,指向結點3(注意我們用臨時變量保存某個結點就是爲了首先斷開該結點和前面結點之間的聯繫,這可以當作一個規律記下來),然後我們斷開結點2和結點3,將結點2的next連到結點4上,也就是 cur->next = t->next,再把結點3連到結點1的後面結點(即結點2)的前面,即 t->next = pre->next,最後再將原來的結點1和結點2的連接斷開,將結點1連到結點3,即 pre->next = t。這樣我們就完成了將結點3取出,加入結點1的後方。第二步將結點4取出,加入結點1的後方,也是同樣的操作。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
dummy = ListNode(-1)
dummy.next = head
pre = dummy
for i in range(m-1):
pre = pre.next
cur = pre.next
for _ in range(m, n):
t = cur.next
cur.next = t.next
t.next = pre.next
pre.next = t
return dummy.next