题目
给定一个单链表的头节点 head,实现一个调整单链表的函数,使得每K个节点之间为一组进行逆序,并且从链表的尾部开始组起,头部剩余节点数量不够一组的不需要逆序。(不能使用队列或者栈作为辅助)
例如:
链表:1->2->3->4->5->6->7->8->null, K = 3。
那么 6->7->8,3->4->5,1->2各为一组。
调整后:1->2->5->4->3->8->7->6->null。
其中 1,2不调整,因为不够一组。
解法
首先,这里先分为几个子部分进行分析:
1. 翻转链表
整体使用递归的思想。
若size为1时,翻转不发生,返回自身。
若size为2时,翻转的方式为:tail->next = head; head->next = nil; 然后返回tail。
若size大于2,则将head后面的子链表继续递归,之后与head进行操作:result->next = head; head->next = nil; 最后返回result。
|
|
2. 链表分组。
还是使用递归的思想。
从头遍历链表,取出指定索引为k的子链表。
若子链表个数不够,根据题目要求,不翻转,直接返回。
若子链表符合要求,将此子表与其他部分分割为两个链表。
将子表翻转并返回;其他部分则继续进行递归操作。
最后,合并两部分,则得到最终结果链表。
|
|
3. 从前向后 -> 从后向前
由于单链表访问的局限性,我们只能从头向后访问,因此,此题目我们转化为从前向后的分组翻转(两次翻转,负负得正):
- 整体链表翻转。
- 从前向后进行分组操作。
- 将结果链表再次整体翻转,得到最终结果。
|
|
代码地址:GroupAndReverse
参考链接:
一道字节跳动的算法面试题,你能做出来吗?