LeetCode 206 反轉鏈表 題解

反轉一個單鏈表。

示例:

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

經典題目。。分別用遞歸和循環實現。

1.循環,比較好理解。

首先定義三個指針代表三個節點(圖第一步)。第一個指針pre,是用於把第二個指針cur指向它(反轉)(圖第二步),第三個指針next,是爲了反轉後,將第二個指針cur往後挪一挪(cur = next),當然同時另外兩個指針都要一起挪一挪。如圖的第三步。

然後注意循環結束條件,我這裏寫的是next != null,但是next == null的時候,情況是這樣子的,如圖

也就是說最後一次循環走不進去,但是還要把最後一個節點反轉一下,所以return前需要 cur.next = pre ,在return cur回去。

代碼:

class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null) return null;
        
        ListNode preNode = null;
        ListNode curNode = head;
        ListNode nextNode = head.next;
      
        while(nextNode != null){
            curNode.next = preNode;
            preNode = curNode;
            curNode = nextNode;
            nextNode = nextNode.next;
        }        
        curNode.next = preNode;
        return curNode;
    }
}

2.遞歸

class Solution {
    
    //代表將一個鏈表反轉,並返回反轉後的頭部。
    public ListNode reverseList(ListNode head) {
        
        if(head == null) return null;  //輸入爲null的情況
        if(head.next == null) return head;     //遞歸到最後只有一個節點的情況,將自己返回去,該節點肯定爲 每次遞歸結束後返回的頭節點。
        
        ListNode headNode = reverseList(head.next);  //一直遞歸。對應上一行代碼,每次返回的肯定都是同一個頭結點,所以最後返回該節點
        
        ListNode curNode = headNode;              //對於每一層遞歸而言,需要將當前的head放到 反轉後的鏈表 的後面,同時把他自己的指向置爲null(ps:看了官方題解後,發現其實就是head.next.next = head(因爲 當前head 其實還指向 反轉後的鏈表 的尾部,只要將他們反指就好了)我是從頭開始遍歷找到最後一個節點,然後將 反轉後的鏈表 的最後一個節點 指向 當前head,可能效率低了一點,)
        while(curNode.next != null){
            curNode = curNode.next;
        }                                                        //這幾行 等同於 head.next.next = head,上面有解釋原因。。
        curNode.next = head;
        head.next = null;
        
        return headNode;        
    }
}

 

 

ps:官方代碼:

public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) return head;
    ListNode p = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return p;
}

 

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