力扣第六十一题-旋转链表

338 阅读2分钟

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

前言

力扣第六十一题 旋转链表 如下所示:

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

示例 1:

输入: head = [1,2,3,4,5], k = 2
输出: [4,5,1,2,3]

示例 2:

输入: head = [0,1,2], k = 4
输出: [2,0,1]

一、思路

这一题题目意思比较容易理解:就是将链表尾部 k 个元素放置到链表的头部中

我一开始使用快慢指针写的,但是不太好处理 k > head.len 的情况。例如示例2中的 head = [0,1,2], k = 4 就是 k > head.len

所以我就换了一种思路,实现的步骤大致分为以下两个步骤:

  1. 将链表的尾部指向头部形成圆环,此时临时指针 headTemp 指向链表尾部
  2. 再找到圆环断开的位置
  3. 返回新的头节点 newHead

图解算法

此处以 head = [1, 2, 3, 4, 5], k = 12 作为例子

  1. 先将尾部指向头部形成圆环

image.png

  1. 找到圆环断开的位置

我们知道临时指针 headTemp 在形成圆环时指向链表的最后一个节点,即 5

image.png

我们知道当 k = 1 时,圆环应该在 4 -> 5 断开,此时从临时指针开始需要走的步数为 p = 4,如下图所示:

image.png

k = 2 的时候,圆环应该在 3 -> 4 断开,此时从临时指针开始需要走的步数为 p = 3,如下图所示:

image.png

我们发现断开的位置是从后往前的,当 k == head.len,即 k == 5 时,相当于发生了一次循环。圆环应该在链表的尾节点指向头节点的地方断开,即 5 -> 1 的地方。如下图所示:

image.png

综上所述,断开的位置为:从临时指针 headTemp 开始,走 p = len - k % len 步即可断开(为了走最少的步数,所以进行了取余)

所以 k = 12 断开的位置为从临时指针走 p = 5 - 12%5 = 3 步断开,如下图所示:

image.png

二、实现

实现代码

实现代码与思路中保持一致,值得注意的是当 head == null 时直接返回结果 null 即可。

    /**
     * 链表转圆环
     */
    public ListNode rotateRight(ListNode head, int k) {
        // 特殊情况
        if (head == null) {
            return null;
        }
        // 先把它变成一个圆
        int len = 0;
        ListNode headTemp = head;
        while (true) {
            len++;
            if (headTemp.next == null) {
                headTemp.next = head;
                break;
            }
            headTemp = headTemp.next;
        }
        // 看在哪里断开
        int p = len - k % len;
        while (p > 0) {
            headTemp = headTemp.next;
            p--;
        }
        ListNode newHead = headTemp.next;
        headTemp.next = null;
        return newHead;
    }

测试代码

    public static void main(String[] args) {
        ListNode listNode = new ListNode(1, new ListNode(2, new ListNode
        (3, new ListNode(4, new ListNode(5)))));
        new Number61().rotateRight(listNode, 12);
    }

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~