LeetCode 25. K 个一组翻转链表

一、题目描述

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

示例 2:

输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]

二、思路

相比于简单的反转链表,本题在反转链表的条件上增加了计数条件,这将用到遍历,将反转的链表分成了一些长度相等的小块并连接,反转后,被反转的链表的头节点和尾节点应该怎么样与前后衔接,这些都是我们要解决的问题,我们逐步分析

三、实现步骤

(1)首先封装一个反转链表的函数

  ListNode* reversalList(ListNode* head){
        ListNode* pre=nullptr;
        ListNode* cur=head;
        while(cur){
        ListNode* temp=cur->next;
        cur->next=pre;
        pre=cur;
        cur=temp;
        }
        return pre;
   }

(2)因为伴随着反转链表,头节点head会发生变化,所以先创建一个虚拟头节点dummy来固定链表

        ListNode* dummy=new ListNode(0);
        dummy->next=head;

(3)将链表分成很多长度相等的小块,这里用到了遍历的思想,首先创建两个节点node1 node2指向dummy

ListNode* node1=dummy,*node2=dummy;
while(node1->next){
    //将node1指向这个k个规模小块的末尾
    for(int i=0;i<k&&node1;i++){
         node1=node1->next;
    }
}

还有个很重要的条件,因为我们会为node1的下一个节点创建一个指针,所以node1的下一个节点不能为空,否则会报错,这也是我运行中碰到的错误

f(node1==nullptr){
    break;
}

(3)第一次找到应该分的小块后,我们就可以进行第一次操作了,给node1的下一个节点定义一个指针node4,以保存该节点,定义一个指针指向该小块的第一个节点,记得断开链表,再将这个小块反转

istNode* node4=node1->next;
ListNode* node3=node2->next;
node1->next=nullptr;
node2->next=reversalList(node3);

(4)反转链表后,下一步进行缝合操作,并移动其它节点准备进行下一次操作

            node3->next=node4;
            node2=node3;
            node1=node3;

(5)直到遍历工作全部完成后,返回最初保存的dummy->next即可

四、具体算法代码实现

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* dummy=new ListNode(0);
        dummy->next=head;
        ListNode* node1=dummy,*node2=dummy;
        while(node1->next){
            for(int i=0;i<k&&node1;i++){
                node1=node1->next;
            }
            if(node1==nullptr){
                break;
            }
            ListNode* node4=node1->next;
            ListNode* node3=node2->next;
            node1->next=nullptr;
            node2->next=reversalList(node3);
            node3->next=node4;
            node2=node3;
            node1=node3;
    }
    return dummy->next;
}
private:
   ListNode* reversalList(ListNode* head){
        ListNode* pre=nullptr;
        ListNode* cur=head;
        while(cur){
        ListNode* temp=cur->next;
        cur->next=pre;
        pre=cur;
        cur=temp;
        }
        return pre;
   }
};

五、总结

链表题的解法大体都有相似的地方,先确定要用到些什么步骤和功能,再通过画图模拟过程来加深对过程的理解,再将图里面的东西转换成算法语言即可

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值