LEETCODE解题笔记 —— 24.两两交换链表中的节点 & 25. K 个一组翻转链表

本文介绍了一种局部反转链表的方法,通过递归实现,并详细解释了关键步骤和注意事项,如处理前驱节点以避免丢失链表节点。

常作题,常更新。

 

这类题就是和反转链表有关,有两种思路,一种是维护几个指针顺着链表一个一个做处理。

这样效率比较高,但是确实比较繁琐。

另一个是用递归的思想来翻转链表,一层层递归下去,在函数出栈的时候让下一个节点的指针指向自己,因为使用了函数栈来记录每个节点的指针,所以代码实际上更简单了。

 

下面要要记录的是翻转链表的一个变体,即在链表中部分翻转链表。

下面是 25题的解,25题其实是24题的通用形式。

 

class Solution {
public:
    int count;
    ListNode* new_head;  //新的头
    ListNode* old_next;  // 第K+1个节点
    ListNode* pre;       //前驱
    bool partial_reverse(ListNode* p, int n)
    {
        if (p == nullptr) //没到数量就空了,说明不能翻转
        {
            return false;
        }
        if (n == count) //新的头部找到了,如果有前驱就把前驱的next指向它
        {
            old_next = p->next;
            new_head = p;
            //连上
            if (pre)
            {
                pre->next = new_head;
            }
            return true;
        }
        if (partial_reverse(p->next,n+1))  //递归到下一层,没问题就把下一层的next指向这层
        {
            p->next->next = p;
            if (n == 1)
            {
                p->next = old_next;   //新尾巴指向原来的后驱
                pre = p;              //新尾巴变成前驱,为下k个链表的反转做准备。
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        if (k == 0 || k == 1) return head;
        count = k;
        new_head = nullptr;
        old_next = nullptr;
        pre = nullptr;
        ListNode* p = head;
        ListNode* res = head;
        int i = 0;
        while(partial_reverse(p,1))
        {
            if (i == 0)
            {
                res = new_head;
                i++;
            }
            p = old_next;
        }
        return res;
    }
};

注意 partial_reverse()函数,这个函数会反转部分链表,返回反转情况,如果剩下的节点不够k个,就会反转失败,返回false

利用class的特性,这个函数得以简化,和他相关的参数 :

count 是 k,子链表长度, new_head即反转后子链表的新头部,

old_next是子链表尾部的next,毕竟是在一个链表里做部分反转,所以还是要记下来,

pre是子链表的前驱

示意图如下:

pre —— sub list —— old_next

 

之前老是忘记处理pre这个节点,pre->next记录的是反转前的头节点,如果反转后不把pre->next指向新的头节点,会导致整条链表丢节点。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值