1. 程式人生 > >LeetCode-206. Reverse Linked List

LeetCode-206. Reverse Linked List

Description

這裡寫圖片描述

Solution 1(C++)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        while(head==NULL||head->next
==NULL) return head; ListNode *first=head; ListNode *second=head->next; first->next=NULL; while(second != NULL){ ListNode *third=second->next; second->next=first; first=second; second=third; } return first; } };

Solution 2(C++)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* new_head = new ListNode(0);
        new_head -> next
= head; ListNode* pre = new_head; ListNode* cur = head; while (cur && cur -> next) { ListNode* temp = pre -> next; pre -> next = cur -> next; cur -> next = cur -> next -> next; pre -> next -> next = temp; } return new_head -> next; } };

Solution 3(C++)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *pre=NULL;
        while(head != NULL){
            ListNode *temp=head->next;
            head->next=pre;
            pre=head;
            head=temp;
        }
        return pre;
    }
};

演算法分析

這道題第一次完全做對,基本掌握了連結串列指標的用法。確實,連結串列題感覺指標用的挺多,所以這裡附上網上找到的指標學習指南,做一個複習:深度長文教你徹底掌握C++/C指標

說白了,牢記一點,指標是一個數據型別,與int、double、char沒什麼區別,只是,它專門用來儲存地址,所以指標就是一個地址變數,只是,這個地址變數可以通過解地址符:*,來獲取地址指向的變數。明白了這一點,就知道如何做連結串列的題了。

演算法簡單說一下,我的方法就是從前往後,改變結點之間的指向方向,反過來就可以了。只是需要迴圈的構建。還有返回值的選取,由於迴圈條件設定的是second != NULL,所以當迴圈結束時,second就是NULL,那麼,first就是原連結串列尾結點,也是新連結串列的頭結點,所以返回first就可以了。

這道題最重要的一點就是有一個連結串列出現的BUG,放在程式分析中說。

解法三: 解法三是在做了234題之後,想重新溫習一下,那麼這裡就說一下溫習所得。pre其實就是head之前的結點,head是當前的結點,temp是head下一個結點。所以,pre初值為NULL,那麼對於一個head:

第一步,將head下一個結點儲存在temp中。
第二步,讓head的下一個結點指向前一個結點pre。至此,完成連結串列指向反轉,下面要進行變數的更新。
第三步,將pre更新為現在的head;將現在的head更新為temp。
第四步,進行迴圈,當head為NULL時,說明連結串列遍歷完成,返回head前一個結點,即pre。

程式分析

在做這道題的時候一直出一個BUG。如果將:

while(head==NULL||head->next==NULL) 
    return head;

這一句刪掉,那麼就會出現如下的BUG資訊:
這裡寫圖片描述
錯誤提示:

    ListNode *second=head->next;

這一句出現了問題。想了半天沒找到答案,後來在網上找到了參考的資料: