leetcode上关于两道链表反转题的解法

链表题,图解是行之有效的方法。
本博客总结迭代法,也就是原地反转

1.反转整个链表

在这里插入图片描述

如图所示,我们定义两个指针指向该链表。其中一个前驱指针pre初始化为空节点,它的next指针指向head(相当于虚拟了一个头节点)。另外一个当前指针cur初始化为头节点
在这里插入图片描述
那么,我们要使得1->2 变为2->1。就是使得 cur->nexrt = pre。但是这样操作会使得2这个节点丢失了。所以我们要定义一个临时节点temp把2保存下来,也就是`‘ListNode * temp 。操作完之后如下图:

在这里插入图片描述
那么接下来,只要迭代就行了,即:pre=cur;cur=temp;。跳转到下一个状态:
在这里插入图片描述

注意,我们每次反转的是当前节点 cur的next指针)可看上面图解。

接着上述三个操作,我们看看迭代终止条件是什么:我们需要一直反转到5节点的next指针,也就是
在这里插入图片描述
可看到,当5节点的next指针被反转后,pre和cur节点依次后移一个,此时pre节点为5节点,cur指向空节点。
所以我们得到迭代终止条件,即:cur==null,此时新链表的表头为pre节点

综上所述,我们可以得到链表反转的代码:

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        //不能给-1节点,否则最后反转后会多出来一个。
        ListNode *cur = pHead;
        ListNode *pre = nullptr;
        ListNode *temp;
        while(cur!=nullptr)
        {
            temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
        //画图可知,最后一次反转链表后,cur->next指向null了,故返回pre。
    }
};

2.反转部分链表

如题:我们需要反转给定区间内的链表节点。

思路跟第一题很相似,在第一题时,我们反转的是从head开始到链表尾部。本题,我们只要找到需要反转的开始部分作为head节点后,剩下的操作跟前面的类似。如下图:即找到下图状态为初始状态即可。
在这里插入图片描述
前面我们说过,上述迭代反转的方式,是反转当前节点cur的next指针,所以开始迭代时,我们需要使得pre初始化为2,cur初始化为3。

同时最后我们需要使得1节点指向4节点,所以我们需要记录下pre的前一个节点1

接着我们来看看终止状态,在反转4节点的next指针后,pre和cur依次后移一位。如下:
在这里插入图片描述

最后我们可以看到 1-2和4-5之间的指针是断开了,我们需要1->4,2->5。
这时,我们前面保存下来的临时节点temp起作用了。
即:

        temp->next->next = cur;// 顺序不能颠倒,否则报错
        temp->next = pre;

注意这里顺序不能颠倒,颠倒的话就变为1->4->5了。因为temp->next->next变了。

在这里插入图片描述


class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode *new_head = new ListNode(0);
        new_head->next = head;
        ListNode *pre =  new_head;
        for(int i=1;i<m;i++) //找到1这个节点
        {
           pre = pre->next;
        }
        ListNode* temp = pre;
        
        pre = pre->next;  //2节点

        ListNode * cur = pre->next; //3节点
        ListNode*temp_1; //迭代的临时节点

        for(int i=m;i<n;i++)
        {
            temp_1 = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp_1;
        }
        temp->next->next = cur;// 顺序不能颠倒,否则报错
        temp->next = pre;
        return new_head->next;
    }
};

`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

通信仿真爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值