算法通关村第一关——链表经典问题之旋转链表笔记

296 阅读1分钟

leetcode 61. 旋转链表

注意:首先一定要求出链表的长度 len,和题目给定的 k 值进行比较;如果 k > len,就要考虑取模 k=k % len; 保证 k < len; 当链表长度小于 k 时,情况如下图所示; image.png

解题思路:使用快慢指针 fast, slow;让快指针先走 k 步,然后快慢指针一起走;这样当快指针来到链表结尾时,保证慢指针slow指向倒数第k个节点,即 slow.next 即是第 k个节点;然后想办法拼接 第 k 个节点之后的链表,和第k个节点之前的链表结构,得到目标链表,返回即可; image.png

// 假设给定链表head 为 1-->2-->3-->4-->5
public static ListNode rotateKthListNode(ListNode head, int k) {
    // 如果 链表为 null,或者 k==0 直接返回head即可
    if (head == null || k == 0) {
        return head;
    }
    // 记录链表长度
    int len = 0;
    // 使用temp作为中间节点遍历链表
    ListNode temp = head;
    while (temp != null) {
        len++;
        temp = temp.next;
    }
    // 如果 k%len == 0; 说明链表移动k位后还是会回到原来的链表结构,直接返回head即可;
    if (k % len == 0) {
        return head;
    }
    // 使用快慢指针
    ListNode fast = head;
    ListNode slow = head;
    // 让快指针先走 k 步;保证 fast指针来到链表的最后位置时,slow.next指向第 k 个节点
    while ((k % len) > 0) {
        fast = fast.next;
        k--;
    }
    // 快慢指针一起走,直到fast来到链表结尾位置;
    while (fast.next != null) {
        fast = fast.next;
        slow = slow.next;
    }
    // res为返回的链表 此时的res链表结构为 4-->5(fast)-->null
    ListNode res = slow.next;  
    // 此时让 slow.next指向null, 这样原来的head链表结构变成 1-->2-->3-->null
    slow.next = null;
    // 让fast指针指向原来的head; 使得 res链表结构变为 4-->5-->1-->2-->3-->null;
    fast.next = head;
    return res;
}

画图来解释返回前的最后三步;

image.png

问题得以解决!!!

image.png