【困难】25-K 个一组翻转链表 Reverse Nodes in k Group

题目

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

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

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

示例:

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

说明:

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

解法

方法一:逐段翻转

解题思路

首先明确反转链表的算法:

那么对于k个一组的翻转链表问题,如果链表长度为n,那就是n/k个子问题,而对于每个子问题的初始化:

  1. res是前一个子问题最后的curr/初始化
  2. head和curr是前一个子问题的end
  3. end是head后的第k个节点
  4. next是curr的next,record是next的next

所以只要重复子问题的解决过程即可(先判断是否有k个节点可以翻转,也就是end是否存在),要注意的是,每次完成子问题之后,还要把他与前面的子问题k串连起来,也就是前一个问题的head与后一个问题最终的curr相连,返回的结果就是第一个k串最终的头

代码

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head == NULL or head->next == NULL) return head;
        ListNode *result = new ListNode(0), *res = result, *curr = head, *end = head;
        res->next = head;
        while(curr){
            ListNode *subhead = curr;
            ListNode *next = curr->next;
            for(int i = 0; i < k; ++i){ // if end exists
                if(end != NULL) end = end->next;
                else return result->next;
            }
            for(int i = 0; i < k-1; ++i){
                end = next->next;
                next->next = curr;
                curr = next;
                next = end;
            }
            subhead->next = end;
            res->next = curr;
            res = subhead;
            curr = end;
        }
        return result->next;
    }
};

方法二:栈

解题思路

每k个节点放入栈,弹出来后自然就是翻转的了,只是要注意如果不够k个的时候,需要把正序的第一个与已有的最后一个相连

代码

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        stack<ListNode*> s;
        ListNode* res = new ListNode(0), *curr = head, *end = res;
        while(true){
            int count = 0;
            ListNode *start = curr;
            for(count=0; count<k; ++count){
                if(!curr) break;
                s.push(curr);
                curr = curr->next;
            }
            if(count != k){
                end->next = start; 
                break;
            } 
            while(!s.empty()){
                ListNode * temp = s.top();
                end->next = temp;
                end = end->next;
                s.pop();
            }
        }
        return res->next;
    }
};
posted @ 2020-04-27 15:47  陌良  阅读(174)  评论(0编辑  收藏  举报