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;
    }
};

算法分析

LeetCode上第二道链表题,第一道可参考: LeetCode-237. Delete Node in a Linked List

这道题第一次完全做对,基本掌握了链表指针的用法。确实,链表题感觉指针用的挺多,所以这里附上网上找到的指针学习指南,做一个复习:深度长文教你彻底掌握C++/C指针

说白了,牢记一点,指针是一个数据类型,与int、double、char没什么区别,只是,它专门用来储存地址,所以指针就是一个地址变量,只是,这个地址变量可以通过解地址符:*,来获取地址指向的变量。明白了这一点,就知道如何做链表的题了。

算法简单说一下,我的方法就是从前往后,改变结点之间的指向方向,反过来就可以了。只是需要循环的构建。还有返回值的选取,由于循环条件设定的是second != NULL,所以当循环结束时,second就是NULL,那么,first就是原链表尾结点,也是新链表的头结点,所以返回first就可以了。

这道题最重要的一点就是有一个链表出现的BUG,放在程序分析中说。

这道题在后面的题目也遇到: LeetCode-234. Palindrome Linked List

解法三: 解法三是在做了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;

这一句出现了问题。想了半天没找到答案,后来在网上找到了参考的资料:

然后,关于这个BUG我自己的解决方法,提供如下:LeetCodeBug-member access within null pointer of type ‘struct ListNode’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值