牛客题霸反转链表C++版题解

牛客题霸NC78反转链表
题目链接:https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca?tpId=188&&tqId=36311&rp=1&ru=/ta/job-code-high-week&qru=/ta/job-code-high-week/question-ranking

我的题解:
首先要明确这道题总体的思路是通过借助指针操作来使链表反转,我们首先考虑非初始状态下的情景,如图1所示,原始的链表在被反转的过程中,可以将它看作两部分已进行反转的部分和尚未反转的部分,我们设“当前指针cur”指向的节点是未反转部分的头结点,接下来我们想要将这个结点添加到已反转的部分,使该结点成为已反转部分的头结点。
cur指向未反转部分的头结点
图1
这就很容易联想到我们首先要找到已反转部分的头结点,我们设置一个“前驱指针pre”指向已反转部分的头结点,再让“当前指针cur”的next指向已反转部分的头结点,即cur->next=pre,就能将cur指向的当前结点已反转的部分连接起来,此时cur成为了已反转部分的头指针,如图2所示。
如何将未反转部分的头结点加入已反转部分
图2
那么问题来了,现在我们找不到未反转部分的头指针了呀,所以还需要一个“后继指针nex”来保存“当前指针cur”指向的结点在还未进入已反转部分时的下一个结点,也就是在进行cur->next=pre之前,先要保证cur所指向结点的下一个结点的地址已经被保存,即先保证已经nex=cur->next,再执行cur->next=pre,如图3、图4所示。
这样我们一共需要三个指针:指向已反转部分头结点的pre,指向未反转部分头结点的cur和为了反转后依然能找到未反转部分的头结点而事先指向cur->next的nex。
cur指向结点加入已反转部分之前
图3
cur指向结点加入已反转部分之后
图4
想要进行下一次反转操作时,之前的cur就要作为pre了,所以让pre=cur,之前的nex是现在的cur,所以让cur=nex,现在的nex的指向则需要再后移一个结点,即nex=cur->next,如图5所示。然后就可以进行反转操作了,执行cur->next=pre,就将尚未反转部分的头结点加入了已反转部分,再去让pre=cur、cur=nex、nex=cur->next,如此循环直到当前指针cur指向为NULL,说明原始链表中的结点已经全部属于已反转后的链表了。
准备将下一个结点反转的链表
图5
下面我们从初始状态来分析,初始状态还没有已反转的部分,所以pre指向NULLcur指向原始链表的头结点pHead,所以程序初始化为pre=NULL,cur=pHead,nex=cur->next,虽然pre为空但是其实原理同上面一样,初始化之后进行while循环,在循环内执行cur->next=pre,此时链表就已经分成了已反转和未反转的两部分,然后执行pre=cur、cur=nex、nex=cur->next,如图6所示。之后继续执行循环,直到cur指向NULL时,说明当前已经没有结点需要加入已反转的部分了,此时pre指向的即是反转完成后链表的头结点,返回pre即可,如图7所示。
从初始状态开始的操作
图6
反转完成
图7

按照以上思路代码如下:

class Solution {
public:
ListNode ReverseList(ListNode* pHead) {
ListNode *pre = NULL;
ListNode *cur = pHead;
ListNode *nex = cur->next; //这里也可以初始化为NULL,但那就要循环内部要先对nex赋值
while (cur) {
cur->next = pre;
pre = cur;
cur = nex;
nex = cur->next;
}
return pre;
}
};

其中,nex初始化时也可以初始化为NULL,此时在while循环中要先进行nex = cur->next;,这样可以保证最后一次循环结束时,cur和nex都是指向NULL,而我这种写法,最后nex指向了NULL的next,有点怪怪的感觉,但是这样写代码也可以通过,而且nex一直都是cur->next。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值