美文网首页
算法-链表每k位逆序

算法-链表每k位逆序

作者: zzq_nene | 来源:发表于2020-07-28 15:42 被阅读0次

    链表的每K位逆序,其实主要的思路就是三个步骤:
    1.找到k个节点的开始节点和结束节点,还有当前这k个节点的最后一个节点的下一个节点
    2.对k个节点做链表反转
    3.将当前k个节点反转后的最后一个节点定义为下一组k个节点的上一个节点,重新找到下一组k个节点的开始节点,并将反转后的k个节点链表重新与完整链表进行连接

        public static ListNode reverseKListNode(ListNode head, int k) {
            if (head == null) {
                return null;
            }
            if (head.next == null) {
                return head;
            }
            if (k < 2) {
                return head;
            }
            // k个节点的最左边的上一个节点
            ListNode pKLeft = null;
            // k个节点的最右边的下一个节点
            ListNode pKRight = null;
            // k个节点的最左边节点,逆序之后在k个节点的最右边
            ListNode kStart = head;
            // k个节点的最右边节点,逆序之后在k个节点的最左边
            ListNode kEnd = null;
    
            // 遍历整个链表的当前节点
            ListNode cur = head;
    
            int count = 1;
    
            while (cur != null) {
                if (count == k) {
                    // 其实就是在第一组的时候,将第一组k个元素反转之后得到的元素末尾作为新的head
                    head = kEnd == null ? cur : head;
                    kEnd = cur;
                    // 当前这k个节点链表的最右边节点的下一个节点
                    pKRight = cur.next;
    
                    // 链表反转-找到前中后三个节点
                    // 反转后kPre依然是这k个节点链表的头节点
                    ListNode kPre = kStart;
                    ListNode kCur = kPre.next;
                    ListNode kNext = null;
                    while (kCur != pKRight) {
                        kNext = kCur.next;
                        kCur.next = kPre;
                        kPre = kCur;
                        kCur = kNext;
                    }
    
                    // TODO 将当前反转的k个节点链表重新与完整链表进行连接
                    // pKLeft是当前这k个节点链表的最左边的上一个节点
                    // kPre是当前k个节点反转后的头节点
                    // 将当前反转的k个节点链表的头部重新加入连接到完整链表中
                    // 其实PKLeft是当前个节点的最左边的上一个,而kPre是当前k个节点反转之后的第一个
                    // 此时需要将之前的k个和当前k个连接起来,所以要使用当前k个的最左边的上一个
                    // 与当前k个反转之后的第一个连接起来
                    if (pKLeft != null) pKLeft.next = kPre;
                    // 这k个节点反转之后,头节点变成了尾节点,那么kStart就变成了这k个节点的尾节点
                    // 所以指向下一个节点
                    // 将当前反转的k个节点链表的尾部重新与完整链表进行连接
                    // kStart是当前k个节点反转之后的最右边节点,让其next指向pKRight,是让当前k个节点与后续节点连接起来
                    kStart.next = pKRight;
                    
                    // TODO 定义下一个k个节点链表的开始节点和其开始节点的前一个节点
                    // 需要进行下一次k个节点的链表反转,则之前k个节点反转之后的的尾巴节点就变成了pKLeft
                    // 将当前反转后的k个节点的尾巴节点变成下一个k个节点的开始节点的前一个节点
                    pKLeft = kStart;
                    // 这里可以直接写pKRight
                    // 定义下一个k个节点的开始节点
                    kStart = pKLeft.next;
                    count = 0;
                    cur = pKRight;
                } else {
                    cur = cur.next;
                }
                count++;
            }
            return head;
        }
    

    相关文章

      网友评论

          本文标题:算法-链表每k位逆序

          本文链接:https://www.haomeiwen.com/subject/szffrktx.html