剑指offer 24.反转链表

反转链表

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

示例:

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

解法一:迭代

重复某一过程,每一次处理结果作为下一次处理的初始值,这些初始值类似于状态、每次处理都会改变状态、直至到达最终状态。

从前往后遍历链表,将当前节点的next指向上一个节点,因此需要一个变量存储上一个节点prev,当前节点处理完需要寻找下一个节点,因此需要一个变量保存当前节点curr,处理完后要将当前节点赋值给prev,并将next指针赋值给curr,因此需要一个变量提前保存下一个节点的指针next。

在这里插入图片描述
1、将下一个节点指针保存到next变量 next = curr.next
2、将下一个节点的指针指向prev,curr.next = prev
3、准备处理下一个节点,将curr赋值给prev
4、将下一个节点赋值为curr,处理一个节点

    //迭代(双指针)
    public ListNode reverseList1(ListNode head){
        ListNode prev = null;//前指针节点
        ListNode curr = head;//当前指针节点
        ListNode temp = null;//临时节点,暂存当前指针的后继节点
        while (curr != null){
            temp = curr.next;//暂存当前指针的后继节点
            curr.next = prev;//改变curr->next的指向
            prev = curr;//前指针后移
            curr = temp;//当前指针后移
        }
        return prev;
    }

时间复杂度 O(N): 遍历链表使用线性大小时间。
空间复杂度 O(1): 变量 pre 和 cur 使用常数大小额外空间。

 

解法二:递归1

以相似的方法重复,类似于树结构,先从根节点找到叶子节点,从叶子节点开始遍历大的问题(整个链表反转)拆成性质相同的小问题(两个元素反转) curr.next.next = curr 将所有的小问题解决,大问题即解决。
在“递”的过程中,在栈中依次保留了所有的前序节点,在“归”的过程中后续节点指向前序节点。

在这里插入图片描述
只需每个元素都执行curr.next.next = curr,curr.next = null两个步骤即可
为了保证链不断,必须从最后一个元素开始

	//curr即传入的head
    public static ListNode reverseList2(ListNode curr) {
        if (curr== null || curr.next == null) {
            return curr;
        }
        ListNode newHead = reverseList2(curr.next);
        curr.next.next = curr;
        curr.next = null;
        return newHead;
    }

 

解法三:递归2

reverse(head,null) 递归函数

终止条件: 当 curr 为空,则返回尾节点 prev (即反转链表的头节点);

递归后继节点,记录返回值(即反转链表的头节点)为 res ;

修改当前节点 cur 引用指向前驱节点 pre ;

返回反转链表的头节点 res ;

请添加图片描述

    public ListNode reverseList3(ListNode head) {
        return recur(head, null);    // 调用递归并返回
    }
    private ListNode recur(ListNode cur, ListNode pre) {
        if (cur == null) return pre; // 终止条件
        ListNode res = recur(cur.next, cur);  // 递归后继节点
        cur.next = pre;              // 修改节点引用指向
        return res;                  // 返回反转链表的头节点
    }

复杂度分析: 时间复杂度 O(N): 遍历链表使用线性大小时间。
空间复杂度 O(N): 遍历链表的递归深度达到 N,系统使用O(N)大小额外空间。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值