LeetCode每日一題:反轉連結串列(No.206)

胖宅老鼠發表於2019-03-24

題目:反轉連結串列


 反轉一個單連結串列。
複製程式碼

示例:


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

進階:
你可以迭代或遞迴地反轉連結串列。你能否用兩種方法解決這道題?
複製程式碼

思考:


首先用遞迴來解決。
如果傳入的節點(head)為null或該節點的next(head.next)為null,則返回該節點。
否則遞迴呼叫自身將下一個節點傳入(head.next)。
再將當前方法中傳入的節點和其後一個節點反轉。
複製程式碼

實現:


  public class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
}
複製程式碼

理解:


LeetCode每日一題:反轉連結串列(No.206)
①處兩行程式碼完成了將傳入的head節點與head.next反轉。
LeetCode每日一題:反轉連結串列(No.206)
②處首先判斷傳入的head節點以及下一個節點head.next是否null,為null就直接返回head節點。
通過不斷的遞迴呼叫reverseList方法,直至傳入的節點為連結串列尾節點時head.next才會為null,直接返回尾節點。
所以newHead節點即為原來連結串列尾節點,反轉後的頭節點。
如果傳入的節點head.next不為null,就是說沒到尾節點,就將head節點與head.next節點反轉。
最終會從遞迴呼叫的最裡層開始,將最後一個節點和倒數第二個節點反轉,再將倒數第二個節點和倒數第三個節點反轉...... 返回結果是newHead節點,就是新的頭節點。

再思考:


首先用迭代法來解決。
用三個指標,head,p,q分別指向頭節點,前一個節點和後一個節點。
然後迴圈每次反轉p與q節點,反轉後將q後移,一直到q為null即連結串列尾部位置。
複製程式碼

實現:


public class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode p = head;
        ListNode q = head.next;
        while (q != null) {
            p.next = q.next;
            q.next = head;
            head = q;
            q = p.next;
        }
        return head;
    }
}
複製程式碼

理解:


如下圖所示,主要是while迴圈中,用三個指標反轉節點,每次反轉後記得修改head的位置和將q向後移。最終head為反轉後列表的頭節點。

LeetCode每日一題:反轉連結串列(No.206)

相關文章