1. 程式人生 > >LeetCode Notes_#206 Reverse Linked List(C++,Python)

LeetCode Notes_#206 Reverse Linked List(C++,Python)

LeetCode Notes_#206 Reverse Linked List(C++,Python)

LeetCode Linked List 

Contents

題目

Reverse a singly linked list.

Example:

Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL

思路

思考

  • 為什麼要使用兩個指標?

    • 因為每次進行逆轉操作必然涉及到兩個節點,head(後)->next = new_head(前),所以必然是兩個指標
    • 兩個指標指向的就是當前操作到的兩個相鄰的節點,另一個角度來說,也可以看做
      1. 正在被拆分的原連結串列的頭,命名為head;
      2. 正在被構造的新連結串列的頭,命名為new_head;新連結串列往前延伸(這也有點和慣常思維不一樣),好像一個棧,從頂部加入新元素,先加入的反而排在後面
    • 嚴格來說是三個,為了不斷遍歷,一開始還需要把head->next備份下來。正是由於指標有點多,所以很容易糊塗。要時刻明確每一個指標存在的意義。
  • 寫迴圈的思路?

    • 迴圈條件是什麼?
      • 遍歷到連結串列的最後
    • 迴圈體是什麼?
      • 先考慮中間的情況(普遍),再去考慮頭和尾的情況(特殊)
    • 用哪一種迴圈(for還是while?)
      • 因為不確定迴圈次數,所以是while

每次迴圈的操作
每次迴圈的操作

  • 關於連結串列的頭指標?
    • 頭指標直接指向第一個儲存資料的節點
    • 為什麼這題裡邊new_head初始化為Null?
      • 其實並沒有被用到,因為第一次進入迴圈就賦值為new_head = head
      • 初始化為Null只是因為必須初始化.
      • 第一次用到了,其實是作為新連結串列的最後一個節點
      • C++ 不要忘記指標變數的初始化

解答

C++

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* new_head = NULL;
        while(head){
            ListNode* next = head->next;
            head->next = new_head;
            new_head = head;
            head = next;
        }
        return new_head;
        
    }
};

Python

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        new_head = None
        while(head):
            next = head.next
            head.next = new_head
            new_head = head
            head = next
        return new_head