想要精通算法和SQL的成长之路 - 旋转链表

想要精通算法和SQL的成长之路 - 旋转链表

  • 前言
  • 一. 旋转链表

前言

想要精通算法和SQL的成长之路 - 系列导航

一. 旋转链表

原题链接
想要精通算法和SQL的成长之路 - 旋转链表_第1张图片
想要精通算法和SQL的成长之路 - 旋转链表_第2张图片

由于k的大小可能超过链表长度,因此我们需要根据链表长度取模。那么我们首先需要去计算链表的长度是多少:

if (head == null) {
    return head;
}
// 计算链表的长度
ListNode tmp = head;
int len = 0;
while (tmp != null) {
    len++;
    tmp = tmp.next;
}
// 取模
k = k % len;

然后,我们用双指针去完成剩余的步骤:

  1. 准备快慢两个指针,分别指向头结点。

  2. fast指针向后移动k位。那次是fast指针后的链表部分。就是需要迁移到链表头部的区域。
    想要精通算法和SQL的成长之路 - 旋转链表_第3张图片

  3. 快慢指针同时向后移动,直到fast指针指向链表的结尾处
    想要精通算法和SQL的成长之路 - 旋转链表_第4张图片

  4. 此时,fast.next应该指向head(此时链表成环),新的头结点应该更细为slow.next,更新完毕后,slow.next断开(解除环)
    想要精通算法和SQL的成长之路 - 旋转链表_第5张图片
    代码如下:

ListNode slow = head, fast = head;
// 快指针先移动k位
for (int i = 0; i < k; i++) {
    fast = fast.next;
}
// 快慢指针同时移动,直到fast到达链表末尾
while (fast.next != null) {
    fast = fast.next;
    slow = slow.next;
}
// 末尾指向原Head,形成环
fast.next = head;
// 认定新的头结点
head = slow.next;
// 解除环状
slow.next = null;

最终完整代码如下:

public ListNode rotateRight(ListNode head, int k) {
    if (head == null) {
        return head;
    }
    // 计算链表的长度
    ListNode tmp = head;
    int len = 0;
    while (tmp != null) {
        len++;
        tmp = tmp.next;
    }
    k = k % len;
    ListNode slow = head, fast = head;
    // 快指针先移动k位
    for (int i = 0; i < k; i++) {
        fast = fast.next;
    }
    // 快慢指针同时移动,直到fast到达链表末尾
    while (fast.next != null) {
        fast = fast.next;
        slow = slow.next;
    }
    // 末尾指向原Head,形成环
    fast.next = head;
    // 认定新的头结点
    head = slow.next;
    // 解除环状
    slow.next = null;
    // 返回新头结点
    return head;
}

你可能感兴趣的:(精通算法和SQL之路,算法,sql,链表)