【力扣算法】92.反转链表II--简单清晰的递归算法-妙啊

题目描述

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

在这里插入图片描述

递归算法

参考:labuladong算法小抄

//结点类型
class ListNode
{
	int val;
	ListNode* next;
}

1、首先对整个链表反转

ListNode* reverse(ListNode* head)
{
	if(head->next == nullptr)
	{
		return head;
	}
	ListNode*last = reverse(head->next);
	head->next->next = head;
	head->next = nullptr;
	return last;
}

2、对链表的前n个结点反转

ListNode* successer = nullptr;
ListNode* reverseN(ListNode* head, int N)
{
	//判断条件修改
	if(N == 1)
	{
		successer = head->next;		
		return head;
	}
	ListNode*last = reverseN(head->next, N - 1);
	head->next->next = head;
	head->next = successer;
	return last;
}

3、对链表的第m - n个结点实现反转

ListNode* reverseBetween(ListNode* head, int M, int N)
{
	//判断条件修改
	if(M == 1)
	{
		return reverseN(head, N);
	}
	head->next = reverseBetween(head->next, M - 1, N - 1);
	return head;
}

方法总结

不要跳进递归,而是利用明确的定义来实现算法逻辑。
例如实现算法1、reverse时,直接将head之后看为一块已经反转的部分,指针last指向这一块的头部,所以需要做的是将这一块的尾部next指针(即head->next->next)指向head,然后head->next指向nullptr即可实现反转,最后返回last即可。

关于递归算法的书写

1、首先要有base case,就是子方法的情况需要考虑退出或者返回相应值
2、状态转移函数,递归调用
3、返回谁

迭代算法

1、首先对整个链表反转

// 反转以 a 为头结点的链表
ListNode reverse(ListNode a) {
    ListNode pre, cur, nxt;
    pre = null; cur = a; nxt = a;
    while (cur != null) {
        nxt = cur.next;
        // 逐个结点反转
        cur.next = pre;
        // 更新指针位置
        pre = cur;
        cur = nxt;
    }
    // 返回反转后的头结点
    return pre;
}

2、前n个结点的反转,左闭右开

/** 反转区间 [a, b) 的元素,注意是左闭右开 */
ListNode reverse(ListNode a, ListNode b) {
    ListNode pre, cur, nxt;
    pre = null; cur = a; nxt = a;
    // while 终止的条件改一下就行了
    while (cur != b) {
        nxt = cur.next;
        cur.next = pre;
        pre = cur;
        cur = nxt;
    }
    // 返回反转后的头结点
    return pre;
}

感觉labuladong算法这里有一个bug,没有把链表连起来。是否应该在返回前执行
a.next = cur; //因为此时cur==b
上述代码实现了b之前的部分的反转,但是a.next此时为nullptr,应该让a指向b位置结点,返回pre即可得到反转的数组

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值