力扣-->剑指Offer 24. 反转链表-->链表-简单(迭代、递归)

剑指 Offer 24. 反转链表
注:本题与206. 反转链表相同

题目描述:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

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

限制:
0 <= 节点个数 <= 5000

206. 反转链表

题目描述:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:
输入:head = []
输出:[]

提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

进阶:
链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

反转链表是很重要的基本功,对于解答很多与链表相关的题目都有很大帮助,也是其基础。

方法一:迭代
迭代法是最直接的将当前链表从前往后逐个反转结点指向的方法,其主要思路为:
1.设置一个当前节点cur初始化为传进来的头结点head,初始化时表示当前节点即为头结点,迭代时表示当前需要处理指向的结点;
2.设置一个前驱结点pre初始化为null,初始化时表示为链表反转后最后一个结点(即初始时的头结点)指向空null,迭代时表示当前节点(本来指向下一个)现在需要指向的结点,即原来的前驱作为现在的后继;
3.开始迭代:只要当前节点非空,
        3.1就将当前结点的下一个结点先用一个临时结点temp保存下来,
        3.2随后即可将当前节点的后继节点改为原来的前驱结点pre,
        3.3改变后就将当前节点作为下一次迭代时的前驱结点,
        3.4最后将当前节点的下一个结点设置为新的当前节点。
4.返回最后的前驱结点pre,因为此时的cur已经为null(原来链表尾部的指向)。

执行结果:通过
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.2 MB, 在所有 Java 提交中击败了52.74%的用户
通过测试用例:27 / 27

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {    //迭代
        ListNode pre=null;//反转后头结点的上一个结点指向空
        ListNode cur=head;//将传进来的节点设置为当前节点,由此开始迭代

        while(cur!=null){//继续迭代
            //由于要反转链表,那么当前节点指向的结点需要改为其上一个结点
            //所以需要将当前节点的写一个结点先保存下来,以免丢失
            ListNode temp=cur.next;
            //保存后就可以开始反转,将当前指针指向其上一个结点
            cur.next=pre;
            //反转后将当前节点设置为所谓的“上一个结点”
            pre=cur;
            //将当前节点的下一个结点设置为所谓的“当前节点”
            cur=temp;
        }
        return pre;//返回头结点,因为最后一次cur=temp;之后cur指向null
    }
}

方法二:递归
递归的关键在于:先递归找到原来的尾节点,将其设置为新的头结点,然后开始跳出递归,此时实现由后向前地获取每个结点(后文的自己),将下一个结点的后继指向自己即可实现反向。

执行结果:通过
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.4 MB, 在所有 Java 提交中击败了13.24%的用户
通过测试用例:27 / 27

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {//递归
        //由于传进来的是head的下一个,所以此处判断的是下一个||下一个的下一个!!
        if(head==null || head.next==null){
            return head;
        }
        //直至得到最后一个结点,即为新的头结点
        //注意此处传进去的是head结点的下一个
        ListNode newHead=reverseList(head.next);
        //最多只会递归到倒数第二个结点,因为最后一个节点已经满足if了,所以不用担心此处的空指针问题
        //即4的下一个的下一个(为5)指向4,由此实现反转--就地反转,但递归需要用栈
        head.next.next=head;
        //需要将当前节点的下一个指向为null,避免最后变成环
        head.next=null;
        return newHead;
    }
}

平平无奇小白程序媛一枚,欢迎各位大佬交流指教,如有不正确的地方,欢迎留言改正,谢谢!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值