📌  相关文章
📜  在给定大小的组中反转双向链表 |设置 2(1)

📅  最后修改于: 2023-12-03 15:08:05.181000             🧑  作者: Mango

在给定大小的组中反转双向链表 | 设置 2

介绍

在给定大小的组中反转双向链表是一道常见的算法问题,使用双向链表实现相对于单向链表更加容易。在这个问题中,输入一个链表的头节点和一个整数k,将链表反转k个节点,并返回反转后的链表的头节点。如果链表中的节点数不是k的倍数,那么最后一个剩余节点应该保持原样。保证链表中的节点数量不会超过 5000。

本题的精髓在于对于双向链表的反转,需要注意next和prev两个指针的变化。同时,对于剩余的不足k个元素,需要特殊处理。这种链表的掌握可以加深我们对链表的理解。

解题思路
  1. 为了能够反转双向链表,我们需要先找到每个要反转的部分的起点和重点。这里我们选择将链表分成k个一组,则每一组的起点为当前节点,终点为当前节点的第k-1个节点,如果到链表的尾部没有k个节点,保持原样。
  2. 遍历每组节点,反转其间的指针,将其转化为单向链表。这一步涉及到指针操作和交换,关键的是需要保存prev变量,对于第一个节点,其prev为null,对于不同组之间的节点,其prev应该是组内的最后一个节点。
  3. 遍历链表,将单向链表转化为双向链表。
代码实现
/**
 * 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时,原链表即为反转后的链表,需要特殊处理。此外,对于链表的基本操作以及指针的理解都会有较大的裨益,并且反转链表在其他题目中也会经常用到。