【JZ-24】反转链表(递归、双指针)

题目

在这里插入图片描述

方法一-迭代(双指针)

遍历链表时,将当前节点的next指针改为指向前一个元素。由于节点没有引用其上一个节点,所以必须先存储其前一个元素,在更改指针方向之前,还需要另一个指针来存储下一个节点。

定义两个指针 p r e pre pre c u r cur cur,初始时 p r e pre pre 指向 null, c u r cur cur指向链表头节点。
每次让 c u r cur cur n e x t next next 指向 p r e pre pre,实现一次局部反转,然后两个指针共同往前走一步 ,重复上述过程直至 c u r cur cur 到达链表尾部。
注意:最后要返回新的头引用!

/**
 * 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 tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
}
  • 时间复杂度: O ( n ) O(n) O(n),n 为链表长度
  • 空间复杂度: O ( 1 ) O(1) O(1)

该方法还可以省一个指针,利用原本的链表头节点指针 head:

class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null)return null;
        ListNode cur = head;
        while(head.next != null){
            ListNode tmp = head.next.next;
            head.next.next = cur;
            cur = head.next;
            head.next = tmp;
        }
        return cur;
    }
}

方法二-递归

递推公式

设 F(n) 代表反转以 h e a d head head 为头节点的单向链表,F(n-1) 代表反转以 h e a d . n e x t head.next head.next 为头节点的单向链表,则递推公式为:
F(n) = F(n-1) + 反转 h e a d head head h e a d . n e x t head.next head.next 之间的指向关系
反转 h e a d head head h e a d . n e x t head.next head.next 之间的指向关系,即执行 h e a d . n e x t . n e x t = h e a d ;   h e a d . n e x t = n u l l head.next.next=head; \ head.next=null head.next.next=head; head.next=null

终止条件

h e a d = n u l l head=null head=null h e a d . n e x t = n u l l head.next=null head.next=null

具体代码

class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null)return head;
        ListNode ret = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return ret;
    }
}

复杂度分析

  • 时间复杂度:O(n),n 为链表长度
  • 空间复杂度:O(n),需要的栈空间大小取决于递归深度,最多为 n 层
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值