206. 92. 25 | 翻转链表 LeetCode
翻转链表,可以通过迭代或者递归来实现,但更好的办法是使用原地翻转算法。这种思想通常是利用额外的指针来保存当前(或下一个)结点的信息来实现的。每次只翻转一个节点。
定义一个额外的指针,指向当前节点(cur)的下一个节点(next)
将当前节点(cur)指向上一个节点(pre)
当前节点(cur)和上一个节点(pre)往前移动一个节点(pre = cur;cur = next;)






分析:
从题干可知,题目要求翻转一个链表中的某一段链表,而不改变链表其他部分。
我们可以将其拆分成几个步骤:
先遍历链表,找到m节点的位置
单独翻转位置m到位置n的链表段
将翻转后的链表段和原链表其余节点连接起来
步骤1和步骤2相对比较简单,只需要按照206.的思路编码即可。步骤3需要考虑以下几种情况:
翻转链表后,尾部节点是否存在未动过的节点?
[1,2,3,4,5], m = 2, n = 4, 此时5未被动过,需把2指向5,1指向4
[1,2,3,4,5], m = 2, n = 5, 此时5也被翻转,因此2指向nullptr
头部节点是否被翻转了?
[1,2,3,4,5], m = 1, n = 4, 由于1翻转后指向5,因此head需要重新指向4
若m > 1,则只需要把1指向翻转后的链表头部即可

继续观察我们可以发现,在步骤2结束后,若最后一个节点也被翻转,则cur == nullptr,所以我们可以将这一步的代码优化:



分析:
结合上面两题来解答,首先遍历k个节点,找到需要翻转的那组节点,然后翻转它,再为翻转后的链表段接上头和尾。注意,最后如果剩余节点小于k的话,则不做任何处理。
找到需要翻转的k链表段
翻转k链表段
将k链表段拼接回原链表
