2022-04-27 12:03阅读: 40评论: 0推荐: 0

力扣-206-反转链表/剑指Offer-24

对于单链表而言,链表的反转需要把节点原本指向下一个节点的指向上一个节点,但是:

  1. 对于任意一个节点而言,它只知道自己的下一个节点而不知道上一个节点

意味着我们需要知道当前节点的上一个节点是谁?

  • 递归:不考虑操作当前节点,操作当前节点的下一个节点,下一个节点上一个节点很明确,就是当前节点
  • 迭代:用pre指针保存上一个节点
  1. 如果修改了节点的next指针(指向上一节点),那么就没法继续向下遍历下一个节点

意味着修改指针前我们要想办法保存下一个节点的信息

  • 通过递归实现了从后往前改,间接通过递归栈保存了遍历路径
  • 迭代:通过nxt指针保存下一个节点

递归

递归是如何解决这两个问题的?

  1. 它向下递归,通过压栈使得倒数第二个节点最先被访问(但是实际处理的是下一个节点,即是最后一个节点)
  2. 它修改的是当前节点的下一个节点,下一个节点的前一个节点我们是知道的,就是当前节点,而当前节点的下一个节点(本应指向前一个节点,但是我们不知道)被置空了

但是这里的置空除了一种情况下,都是没有意义的,因为它会被下一次操作覆盖,没必要特意置空
这中特殊情况就是最后一个,或者说原本的头节点,不会还有操作了,所以必须手动把它的下一个节点指针置空,这就是其他节点都多出了一步的原因

class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 递归的写法其实是相当于从后往前操作
// 每次先向下递归一层,从倒数第2个节点开始操作
// 但也不是操作倒数第二个节点,而是操作它的后一个节点
// 因为不知道当前节点的前一个节点,但是知道后一个节点的前一个节点,就是当前节点
// 每一步都把后一个节点的指针反转
if(!head||!head->next) return head;
ListNode* reversedHead = reverseList(head->next);// 最后一层返回的是最后一个节点,即是新的头节点
head->next->next= head;// 反转下一个节点
head->next=nullptr;// 其实这一句只有在处理最后一个就也就是原本的头节点有效,其余时候都是不必要的
// 只有头节点反转后指向空节点
return reversedHead;// 这个节点在整个递归过程中没有改变
}
};

递归中head指针只改变了next指针的指向,本身没有改变

迭代

迭代又是怎么解决这个问题的?
它用了三个指针

  1. pre用于保存前一个节点,用于反转指针指向
  1. cur用于指向当前节点,用于遍历链表
    但其实不考虑不修改head的话,其实两个指针就够了
    但这样做的话其实是修改了head指针的,如果其他地方要用到head指针的原始值,就不能这么干
  1. next保存下一个节点
// 递归用到的三指针
ListNode* reverseList(ListNode* head) {
// 定义了两个指针
ListNode* pre = nullptr;// 用于保存前一个指针
// 其实两个节点也行,但是head指针会被修改,最后会是一个nullptr
// ListNode* cur = head;// 当前节点指针,用于遍历
while (cur) {
ListNode* nxt = cur->next;// 初始化写到里面来,cur->next可能是空指针
cur->next = pre;// 反转当前指针的指向
// 移动两个指针
pre = cur;
cur = nxt;
}
return pre;// 为什么是pre?cur最后的指向会是空指针
}

这里也很巧妙的解决了输入指针为空,以及链表长度为1的情况

剑指Offer里定义了一个看起来不必要的reversedHead指针用于返回结果,另外,也多了一句无用的判断if(!nxt) reversedHead = head;,可以改写成这样,if(!nxt) return head;,但还是无用
如果这个判断存在,那么这个判断一定会比while中的条件判断先一步出结果,while的条件反而显得多余了,然后由不满足返回值规则
反而,如果去掉,并没有什么影响,用pre指针返回更巧妙,它最终会被更新为指向最后一个节点,也就是反转后的第一个节点

本文作者:YaosGHC

本文链接:https://www.cnblogs.com/yaocy/p/16193916.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(40)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起