【LeetCode算法学习笔记】递归反转链表

labuladong算法公众号学习笔记
labuladong算法公众号学习笔记
labuladong算法公众号学习笔记


单链表的结构:

//单链表节点的结构
public class ListNode{
    int val;
    ListNode nest;
    ListNode(int x) {val=x;}
}

递归反转整个链表

实现代码如下:

ListNode reverse(ListNode head){
    if(head.next == null) return head;
    ListNode last = reverse(head.next);
    head.next.next = head;
    head.next = null;
    return last;
}

对于递归算法,最重要的是明确递归函数的定义。
对于reverse函数:输入一个节点head,将[以Head为起点]的链表反转,并返回反转之后的头节点。
需要注意的地方有两个点:
1、递归函数要有base case。
2、当链表递归反转之后,新的头节点是last,而之前的head变成了最后一个节点,链表的末尾指针要指向Null。

反转链表前N个节点

思路同上:

ListNode successor = null;
ListNode reverseN(ListNode head,int n){
    if(n == 1){
        successor = head.next;
        return head;
    }
    //以head.next为起点,需要反转前n-1个节点
    ListNode last = reverseN(head.next,n-1);
    
    head.next.next = head;
    //让反转之后的head节点和后面的节点连起来
    head.next = successor;
    return last;
}

具体区别:
1、base case变为n == 1,反转一个元素,就是其本身,同时要记录后驱节点。
2、现在head节点在递归反转之后不一定是最后一个节点,所以要记录后驱successor(第n+1个节点),反转之后将head连接上。

反转链表的一部分

给一个索引区间[m,n],仅仅反转区间中的链表元素。
1、如果m==1,就相当于反转链表开头的n个元素。
2、如果m!=1,把head索引视为1,从第m个元素开始反转;把head.next的索引视为1,反转的区间从第m-1个元素开始;…(递归思想)

ListNode reverseBetween(ListNode head,int m,int n){
    //base case
    if(m == 1){
        return reverseN(head,n);
    }
    //前进到反转的起点触发 base case
    head.next = reverseBetween(head.next,m-1,n-1);
    return head;
}

总结

递归处理的技巧是:不要跳进递归,而是利用明确的定义来实现算法逻辑。
处理比较困难的问题,可以尝试化整为零,把一些简单的解法进行修改。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值