LeetCode206.链表反转两种实现

题目描述

反转一个单链表。

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

递归实现

其实拿到这个题目首先应该想到的是递归拆分

步骤解析

1、既然是反转链表,那我们先从最简单的两个节点开始
在这里插入图片描述
2、拿到这个最简单的链表,我们不难看出。因为2的下一个节点是空,所以反转后,2就是头结点。所以,我们可以先肆无忌惮的将2的next属性指向倒数第二个节点,也就是1
在这里插入图片描述
3、因为1刚好是原来的头结点,所以反转后1就变成了尾节点,所以1的next属性就指向了NULL
在这里插入图片描述
4、同理当三个节点的时候也是先变后二,在变前二:
在这里插入图片描述
5、规律
我们可以理解成,从头开始两两去找,找到那个指向Null的节点,然后将这个节点和这个节点的上一个节点先进行反转。
在这里插入图片描述将反转后的链表返回,接着在去上层执行
在这里插入图片描述

6、小结
概括来说,就是将一个链表不断拆分执行相同的操作,当扫描到最后两个节点的时候就开始两两进行反转。

代码实现

public ListNode reseverNode(ListNode head) {
        // 头结点为空返回
        if(head == null){
            return head;
        }
        // 头节点的下一个节点为空,表示只有一个节点,也返回
        if(head.next == null){
            return head;
        }
        //不断两两递归找到最后两个
        ListNode listNode = reseverNode(head.next);
        // head.next的next节点是空,所以一定要先反回来指
        head.next.next = head;
        // 在将头变成尾
        head.next = null;
        return listNode;
    }

迭代实现

反转用迭代的话反而更加方便,也好理解。相当于用一个新的链表,将原来的链表从头开始不断的插入,最后返回新链表,就完成了链表的反转。
在这里插入图片描述

步骤

1、准备好原来的链表和一个空节点
在这里插入图片描述
2、将头节点指向新的节点newList
在这里插入图片描述

然后将newList指向头节点
在这里插入图片描述
head指针指向原先头结点的下一个节点:
在这里插入图片描述
3、我们会发现中间号线断了一层,当执行newList指向头节点的时候,头结点的下一个节点已经被断层了
在这里插入图片描述
所以,我们需要一个变量来保持对**head指向的节点的next的引用**
在这里插入图片描述
此致,大概流程也已经讲述完了。

在这里插入图片描述

代码实现

public ListNode reseverNode2(ListNode head) {
        // 新链表
        ListNode newList = null;
        // 临时节点,存放head.next的
        ListNode temp = null;
        while(head != null){
            // temp存放下一个节点
            temp = head.next;
            // 将头先指向新链表,此时的新链表为空
            head.next = newList;
            // 再将新链表的头指向头结点
            newList = head;
            // 旧链表的头指针指向旧链表的下一个元素
            head = temp;
        }
        return newList;
    }

小结

对于链表反转,个人觉得迭代的方式比递归要好理解一点。但是递归相对来说也没那么难,只要理解成两两组成,两两替换就好了。
关于链表的话,一定要注意先后的问题,如果说某一个地方移动错了,那么会导致元素就找不到了。所以,对于链表来说,执行的先后顺序非常重要。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值