LeetCode刷题笔记 25. K 个一组翻转链表

25. K 个一组翻转链表

题目要求

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例 :

给定这个链表:1->2->3->4->5

当 k = 2 时,应当返回: 2->1->4->3->5

当 k = 3 时,应当返回: 3->2->1->4->5

说明 :

你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

题解

https://github.com/soulmachine/leetcode

递归版

链表的题,多说无益,画图吧。

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head==nullptr||head->next==nullptr||k<2)
            return head;

        ListNode *next_group=head;
        for(int i=0;i<k;++i){
            if(next_group)
                next_group=next_group->next;
            else
                return head;
        }
        // next_group is the head of next group
        // new_next_group is the new head of next group after reversion
        ListNode *new_next_group=reverseKGroup(next_group,k);
        ListNode *prev=nullptr,*cur=head;
        while(cur!=next_group){
            ListNode *next=cur->next;
    //除了第一次,即原来每组最小的数需要指向翻转好的下一组的头之外,都应该指向原来在其之前的元素
            cur->next=prev?prev:new_next_group;
            prev=cur;
            cur=next;
        }
        return prev; // prev will be the new head of this group
    }
};

迭代版

class Solution {
public:
    // prev 是 first 前一个元素, [begin, end] 闭区间,保证三者都不为 null
    // 返回反转后的倒数第 1 个元素(下一组第一个元素之前的位置)
    ListNode* reverse(ListNode *prev,ListNode *begin,ListNode *end){
        ListNode *end_next=end->next;
        for(ListNode *p=begin,*cur=p->next,*next=cur->next;
            cur!=end_next;
            p=cur,cur=next,next=next?next->next:nullptr){
                cur->next=p;
            }
            begin->next=end_next;
            prev->next=end;
            return begin;
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head==nullptr||head->next==nullptr||k<2)
            return head;
        
        ListNode dummy(-1);
        dummy.next = head;

        for(ListNode *prev=&dummy,*end=head;end;end=prev->next){
            for(int i=1;i<k&&end;i++)
                end=end->next;
            if(end==nullptr) break;    // 不足 k 个
            prev=reverse(prev,prev->next,end);
        }
        return dummy.next;        
    }
};
发布了18 篇原创文章 · 获赞 0 · 访问量 1804

猜你喜欢

转载自blog.csdn.net/g534441921/article/details/104128824