leetcode 25. K个一组翻转链表 笔记

题目链接
题目:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5

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

分析:
这题内容看着确实简单,但细想起来却有很多麻烦的地方——需要判断的边界条件/特殊条件太多了,比方说初始元素的个数;指针又该如何放;for循环到哪个边界,边界的节点如何翻转处理。
大概解决方法分成了下面几点:
1、设置含头尾指针参数的翻转函数,用于k个结点链表翻转
2、开辟一个ListNode对象,保证for循环可从0开始
3、k个结点链表的翻转函数可以通过头结点连接指点的next来保证for循环不用考虑边界条件。
4、k个结点翻转函数可以返回头指针与尾指针,方便循环中连接k个一组的各个链表

代码:

class Solution {
public:
    pair<ListNode*,ListNode*> reverseList(ListNode* start, ListNode* end) {
        ListNode* prev = end->next;
        ListNode* p = start;
        while (prev != end) {
            ListNode* next = p->next;
            p->next = prev;
            prev = p;
            p = next;
        }
        return{ end,start };
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* ret = new ListNode(0);
        ret->next = head;
        ListNode* pre = ret;
        while (head) {
            ListNode* end = pre;
            for (int i = 0; i < k; i++) {
                end = end->next;
                if (!end) {
                    return ret->next;
                }
            }
            ListNode* nex = end->next;
            tie(head, end) = reverseList(head, end);
            pre->next = head;
            end->next = nex;
            pre = end;
            head = end->next;
        }
        return ret->next;
    }
};

你可能感兴趣的:(算法,leetcode)