逆置链表中包含K个结点的块

[!Tip]

本节源代码见Github链接🔗


问题描述

对于给定大K(K>0),逆置链表中包含K个结点的块。
示例:
输入:1->2->3->4->5->6->7->8->9->10。对于不同的K值,输出为:
当K=2,输出:2->1->4->3->6->5->8->7->10->9;
当K=3,输出:3->2->1->6->5->4->9->8->7->10;
当K=4,输出:4->3->2->1->8->7->6->5->9->10。


核心思路

本题是对17-交换链表中的相邻结点的扩展,核心包含以下几步:

  1. 判断链表当前剩余部分是否还有K个结点,若不足K个,则直接返回;
  2. 逆置当前节点到往后第K个结点;
  3. 将逆置后的最后一个结点的后继指针指向第K+1个结点;
  4. 将当前指针移向第K+1个结点;
  5. 返回指向最新的表头结点的指针。

逆置链表中包含K个结点的块.png


实现代码

【👉🏻>>点击展开查看代码】
        
/**  
 * 逆置链表中包含K个结点的块  
 *  
 * @param headNode  
 * @return org.example.linkedlist.normal.NormalListNode  
 * @author: Max Solider  
 * @date: 2022/10/13 23:39  
 */
 static NormalListNode reverseBlockOfKNodesInLinkedList(NormalListNode headNode, int k) {  
    if (headNode == null || headNode.getNext() == null || !hasKNodes(headNode, k)) {  
        return headNode;  
    }  
    NormalListNode newHead = null;  
    NormalListNode start = headNode;  
    NormalListNode kNode = getKthNode(start, k);  
    NormalListNode kPlusOneNode = kNode.getNext();  
    NormalListNode newStart = reverseBlock(start, k);  
    start.setNext(reverseBlockOfKNodesInLinkedList(kPlusOneNode, k));  
    if (newHead == null) {  
        newHead = newStart;  
    }  
    return newHead;  
}  

/**  
 * 逆置链表块  
 *  
 * @param head 开始结点  
 * @param k    数量  
 * @return 逆置后的链表块头  
 */  
private static NormalListNode reverseBlock(NormalListNode head, int k) {  
    if (head == null || head.getNext() == null) {  
        return head;  
    }  
    NormalListNode cur = head;  
    NormalListNode previous = null;  
    NormalListNode next = null;  
    while (cur != null && k > 0) {  
        next = cur.getNext();  
        cur.setNext(previous);  
        previous = cur;  
        cur = next;  
        k--;  
    }  
    return previous == null ? cur : previous;  
}  

/**  
 * 获取从head开始第k个结点  
 *  
 * @param head 开始结点  
 * @param k    数量  
 * @return 第k个结点  
 */  
private static NormalListNode getKthNode(NormalListNode head, int k) {  
    NormalListNode start = head;  
    while (--k > 0) {  
        start = start.getNext();  
    }  
    return start;  
}  

/**  
 * 判断从head开始,是否还有k个结点  
 *  
 * @param head 开始结点  
 * @param k    数量  
 * @return true 有k个结点,false 没有  
 */  
private static boolean hasKNodes(NormalListNode head, int k) {  
    if (head == null) {  
        return false;  
    }  
    NormalListNode start = head;  
    while (k > 0) {  
        if (start == null) {  
            return false;  
        }  
        start = start.getNext();  
        k--;  
    }  
    return true;  
}
        
    

时间复杂度

时间复杂度为O(n),用于遍历链表。


空间复杂度

空间复杂度为O(n),用于递归。


© MaxSolider all right reserved,powered by Gitbook文件修订时间: 2022-11-07 18:53:43

results matching ""

    No results matching ""