AcWing 35. 反转链表(两种链表两种通法,头插法+原地法)

1.无头结点的链表

在分析整个问题之前,我们先做一个假设。假设“NULL”是一个特殊的“结点”,它只能被其他结点指向而不能指向其他结点。这里一定要强调把NULL作为结点看待。

我们可以做个图:

NULL    1->2->……->n->NULL

其中,最左侧的NULL是新链表的NULL,我们期待的结果是:

NULL<-1<-2<-……<-n    NULL

结合下面的代码,再根据此图进行手动模拟整个过程就能体会到这么做的好处。

1.1双指针头插法

原理是从原链表头部依次取结点,使用头插法插入到新链表中。

具体代码如下:

/**
 * 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 *p, *q;
        p = head;
        head = NULL; //head指向最左侧的NULL
        while(p){
            q = p, p = p -> next;
            q -> next = head;
            head = q;
        }
        return head;
    }
};

1.2三指针原地法

具体代码如下:

/**
 * 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 *p, *q, *r;
        p = head;
        q = NULL; //q指向最左侧的NULL
        while(p){
            r = p -> next;
            p -> next = q;
            q = p, p = r;
        }
        return head = q;
    }
};

2.带头结点的链表

注意:带头结点的链表的反转代码只要将以上两份代码中所有的“head”全部用“head->next”替换即可!

分析过程与上面相似,大家可以结合代码并手动模拟整个过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值