LeetCode25. Reverse Nodes in k-Group

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

k is a positive integer and is less than or equal to the length of the linked 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为例,首先反转两个变成2-1-3-4-5,下一次应该反转3和4,利用reverse仍然可以实现,但要注意的是,反转后的顺序4-3,其中的4必须与前面1联系,而3必须与后面的3联系,否则整个链表就断了。另外,最后只剩下一个5时,其长度已经小于要求的长度2了,这时候应该返回NULL,代表与前面的关系不改变。
首先给出改进的reverse函数,其中head表示当前要反转的链表段的起始位置,n-1表示还剩有多少个数没有完成反转,tail表示这段要反转链表反转后的尾部(其实就是反转前此段链表的头部),begin表示此段链表的前一个结点,在完成反转后必须与前一个结点保持联系。
ListNode* reverse(ListNode* head,int n,ListNode* tail,ListNode* begin){ if(head&&!head->next&&n>1)return NULL; if(n==1){ if(head&&tail)tail->next=head->next; if(begin)begin->next=head; } else if(head&&head->next&&n>1){ ListNode* temp=reverse(head->next,n-1,tail,begin); if(temp)temp->next=head; if(!temp)return NULL; } return head;
}

下面给出调用reverse的代码,首先应该获得第一段反转,如果反转的结果是NULL,说明整个链表的长度都不够,则直接返回原链表即可。否则的话,就找到新链表开始的位置,保存下来,作为最后返回时用。完成第一段反转后,下一段反转的起始应为第一段的末尾的下一个结点,然后继续reverse就ok了。

ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* keep=head;
        int t=k;              
        while(t>1&&keep){
            keep=keep->next;
            t--;
        }
        ListNode* temp=reverse(head,k,head,NULL);
        if(!temp)return head;
        while(temp&&temp->next){
            temp=reverse(temp->next,k,temp->next,temp);
        }
        return keep;
    }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值