LeetCode:206. 反轉鏈表

本文來自 SoulOH 的CSDN 博客 ,原文地址請點擊:https://blog.csdn.net/SoulOH/...
題目:
反轉一個單鏈表。

示例:

輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL

進階:
你可以迭代或遞歸地反轉鏈表。你能否用兩種方法解決這道題?


解答:

迭代方式:

首先判斷鏈表是不是空的,如果是空的,直接返回null;

對於鏈表:

clipboard.png
放兩個指針p1, p2:

clipboard.png
不能直接將p2 -> next指向p1,否則鏈表會斷掉。

clipboard.png
可以設置一個tmp指針,指向 p2 -> next,保證後續的操作:

clipboard.png

clipboard.png
然後將p1,p2往前挪動,當然還有tmp,直到p2爲空,這時p1指向反轉後鏈表的頭結點。

clipboard.png

最後一次:

clipboard.png
剛好結束的時候:

clipboard.png
完成了?

不。好像有一點不對勁兒,還多了一個1 -> 2的指針,少了一個null(1 -> null)。正巧head還在,通過head -> next訪問多餘的指針,指向null(其實一開始就可以這麼幹的。)

clipboard.png

實現代碼:

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    //迭代
    if (head == null || head.next == null) return head;
    var p1 = head;
    var p2 = head.next;
    p1.next = null;
    while (p2 !== null) {
        var temp = p2.next;
        p2.next = p1;
        p1 = p2;
        p2 = temp;
    }
    return p1;
};

遞歸方式:

我們可以從另一個角度考慮這件事:

同樣地,對於這樣一個鏈表:

clipboard.png
我們要反轉它,其實可以

clipboard.png

然後我們當作這個子鏈表已經反轉完成:

clipboard.png
而我們需要的是:

clipboard.png
於是我們可以將上上張圖的head.next.next = head:像是這樣:

clipboard.png
然而僅僅這樣是不夠的,鏈表到現在有一個明顯的環,我們要把這個環去掉:

令head.next = null即可。

clipboard.png
完成。

接下來考慮遞歸結束的條件:非常顯然,子鏈表只有一個節點是遞歸結束,直接返回該節點。

當然,這個可以和一開始的空值處理(空鏈表的處理)寫到一起。

下面是具體實現:

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    //遞歸
    if (head == null || head.next == null) return head;
    var res = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return res;
    
};

本文來自 SoulOH 的CSDN 博客 ,原文地址請點擊:https://blog.csdn.net/SoulOH/...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章