本文來自 SoulOH 的CSDN 博客 ,原文地址請點擊:https://blog.csdn.net/SoulOH/...
題目:
反轉一個單鏈表。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
進階:
你可以迭代或遞歸地反轉鏈表。你能否用兩種方法解決這道題?
解答:
迭代方式:
首先判斷鏈表是不是空的,如果是空的,直接返回null;
對於鏈表:
放兩個指針p1, p2:
不能直接將p2 -> next指向p1,否則鏈表會斷掉。
可以設置一個tmp指針,指向 p2 -> next,保證後續的操作:
然後將p1,p2往前挪動,當然還有tmp,直到p2爲空,這時p1指向反轉後鏈表的頭結點。
最後一次:
剛好結束的時候:
完成了?
不。好像有一點不對勁兒,還多了一個1 -> 2的指針,少了一個null(1 -> null)。正巧head還在,通過head -> next訪問多餘的指針,指向null(其實一開始就可以這麼幹的。)
實現代碼:
/**
* 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;
};
遞歸方式:
我們可以從另一個角度考慮這件事:
同樣地,對於這樣一個鏈表:
我們要反轉它,其實可以
然後我們當作這個子鏈表已經反轉完成:
而我們需要的是:
於是我們可以將上上張圖的head.next.next = head:像是這樣:
然而僅僅這樣是不夠的,鏈表到現在有一個明顯的環,我們要把這個環去掉:
令head.next = null即可。
完成。
接下來考慮遞歸結束的條件:非常顯然,子鏈表只有一個節點是遞歸結束,直接返回該節點。
當然,這個可以和一開始的空值處理(空鏈表的處理)寫到一起。
下面是具體實現:
/**
* 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/...