每日算法——leetcode系列


问题 Reverse Nodes in k-Group

Difficulty: Hard

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For example,

Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        
    }
};

翻译

k个一组反转节点

难度系数:困难

给定一个链表,每次反转k个节点并返回反转后的链表。
如果节点的个数不是k的倍数,节点后面剩下的部分就不用反转。
不能改变节点的值, 只能改变节点的位置
只允许常数级的内存分配。

例如:
给定链表: 1->2->3->4->5

当 k = 2时, 结果应为: 2->1->4->3->5
当 k = 3时, 结果应为: 3->2->1->4->5

思路

此题分三步分析比较容易理解:

  1. 怎么来反转含k个节点的链表?

  2. 怎么来反转含n个节点的前k(n >= k)个节点?

  3. 怎么k个一组反转含n(n >= k)个节点的链表?

上一个题用next代表下一个节点,当next->next这种情况感觉不友好,现用n代表下一个节点
假设: p代表上一个节点,c代表当前节点,n代表下一个节点

  • 第一个问题,主要就是让c->next = p,方法如下图
    图片描述

  • 第二个问题比第一个问题多了一小点东西,就是以前的头节点要指向第k+1个节点

  • 第三个问题,就是反复调第一个问题,就要是保证每次反转的链表节点个数为k,先让一个节点走到第k个节点,再把这个节点作为尾节点

代码

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if (head == nullptr || head->next == nullptr || k < 2){
            return head;
        }
        ListNode dummy(-1);
        dummy.next = head;
        ListNode* p = &dummy;
        
        while(p != nullptr){
         p->next =  reverse(p->next, k);
            for(int i=0; p && i<k; i++){
                p = p->next;
            }
        }
        return dummy.next;
    }
    
private:
    ListNode* reverse(ListNode* head, int k){
        ListNode* tail = head;
        for (int i = 1; i < k && tail != nullptr; ++i){
            tail = tail->next;
        }
        if (tail == nullptr){
            // 节点个数小于k, 这部分不反转
            return head;
        }
        ListNode* p = head;
        ListNode* c =p->next;
        ListNode* tailNext = tail->next;
        while (true) {
            ListNode* cNext = c->next;
            c->next = p;
            if (p == head){
                p->next = tailNext;
            }
            p = c;
            if (c == tail){
                break;
            }
            c = cNext;
        }
        return tail;
    }
};

carlblack
4 声望16 粉丝

下一篇 »
Remove Element