链表中的节点每k个一组进行翻转
题目:
将给出的链表中的节点每k个一组翻转,返回翻转后的链表。
如果链表中的节点数不是k的倍数,将最后剩下的节点保持原样。
不能更改节点中的值,只能更改节点本身。
要求空间复杂度为O(1)
示例:
给定的链表是:1→2→3→4→5
对于k = 2,你应该返回:2→1→4→3→5
对于k = 3,你应该返回:3→2→1→4→5
思路:
① 题目要求我们每k个节点一组进行翻转。所以我们必须要明确每次要翻转的节点的范围。
② 对于我们确定好的范围,我们要进行该范围内的翻转链表。
③ 翻转链表后,又有新的问题,翻转后的链表怎么链到原链表中呢?我们可以通过指针来完成该操作。定义prev指针,用来保存一组待翻转链表的上一个节点,定义start,用来保存待翻转链表的第一个节点。再定义一个指针 next,用来保存待翻转链表的最后一个节点的下一个节点。这样,我们就能轻而易举的将翻转后的链表链到原链表中。
图示:
① 图示为链表初始状态,其中dummy是头结点,无实际意义。end、prev分别指向dummy。我们用 k = 2 来举例。
② 通过end,我们找到了待翻转链表的最后一个节点,然后我们需要找到待翻转链表的第一个节点,定义start指针,指向待翻转链表的第一个节点,然后我们还需要知道待翻转链表的最后一个节点的下一个节点,便于下一次我们找到新的一组待翻转链表的第一个节点。我们使用next指针记录待翻转链表的最后一个节点的下一个节点。如图所示:
此时,翻转start、end范围内的节点,注意在翻转之前,我们应该将end.next置为null。这样才能准确地进行翻转。翻转结果如下图所示:
接着我们将start所指向的节点的next域指向next,**prev指向的节点的next域指向我们新翻转后链表的第一个结点。**如下图所示: