📅  最后修改于: 2023-12-03 15:08:05.181000             🧑  作者: Mango
在给定大小的组中反转双向链表是一道常见的算法问题,使用双向链表实现相对于单向链表更加容易。在这个问题中,输入一个链表的头节点和一个整数k,将链表反转k个节点,并返回反转后的链表的头节点。如果链表中的节点数不是k的倍数,那么最后一个剩余节点应该保持原样。保证链表中的节点数量不会超过 5000。
本题的精髓在于对于双向链表的反转,需要注意next和prev两个指针的变化。同时,对于剩余的不足k个元素,需要特殊处理。这种链表的掌握可以加深我们对链表的理解。
/**
* Definition for doubly-linked list.
* public class ListNode {
* int val;
* ListNode prev;
* ListNode next;
* ListNode(int x) {
* val = x;
* }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null || k <= 1) {
return head;
}
ListNode dummy = new ListNode(-1);
dummy.next = head;
int len = 0;
ListNode curr = head;
while (curr != null) {
len++;
curr = curr.next;
}
curr = dummy;
for (int i = 0; i < len / k; i++) {
ListNode prev = null;
ListNode curGroupLast = curr.next;
for (int j = 0; j < k; j++) {
ListNode tmp = curGroupLast.next;
curGroupLast.next = prev;
prev = curGroupLast;
curGroupLast = tmp;
}
ListNode curGroupFirst = prev;
curr.next = curGroupFirst;
curGroupLast.prev = curr;
curGroupFirst.prev = null;
if (curGroupLast != null) {
curGroupLast.next.prev = null;
}
curr = curGroupLast != null ? curGroupLast : curGroupFirst;
}
return dummy.next;
}
}
本算法的时间复杂度为O(N),其中N表示链表的长度。空间复杂度为O(1),因为我们只用到了常量级别的额外空间。
本题的解法较为经典,非常值得掌握。同时,也要关注到特殊情况,例如当k=1时,原链表即为反转后的链表,需要特殊处理。此外,对于链表的基本操作以及指针的理解都会有较大的裨益,并且反转链表在其他题目中也会经常用到。