LeetCode25. Reverse Nodes in k-Group

题目:对一个链表的长度为k的块进行reverse,要求常数空间。

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


分析:分治法求解

先考虑对一个链表进行reverse操作

举个栗子:

1->2->3->4->5 reverse之后变为 5->4->3->2->1

先用两个指针来把链表的前半部分和后半部分进行交换,时间复杂度O(n)

交换后变为 4->5->3->1->2,继续对子问题进行递归操作,即reverse链表的4->5和1->2部分

两次递归操作后,链表变为5->4->3->2->1

整个操作的时间复杂度为O(nlgn)


对每个长度为k的链表部分进行操作后,就能得到问题的解

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverse(ListNode* head, int k) {
        if (k == 1) { return head; }
        ListNode *i = head, *j = head, *ti, *tj;
        int val;
        for (int n = 0; n < (k + 1) / 2 && j != NULL; n++) {
            j = j->next;
        }
        tj = j;
        for (int n = 0; n < k / 2; n++) {
            if (tj == NULL) { return head; }
            tj = tj->next;
        }
        ti = i;
        tj = j;
        for (int n = 0; n < k / 2; n++) {
            val = i->val;
            i->val = j->val;
            j->val = val;
            i = i->next;
            j = j->next;
        }
        reverse(ti, k / 2);
        reverse(tj, k / 2);
        return head;
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode *p = head;
        while (p != NULL) {
            reverse(p, k);
            for (int i = 0; i < k && p != NULL; i++) {
                p = p->next;
            }
        }
        return head;
    }
};

>.<


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值