前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >互联网算法面试题之旋转链表

互联网算法面试题之旋转链表

作者头像
程序员小熊
发布2021-05-28 12:29:55
2360
发布2021-05-28 12:29:55
举报
文章被收录于专栏:程序员小熊 带你学算法

关注下方公众号,分享满满的干货

61. 旋转链表

描述

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

解题思路

思考

考虑以下几种情况:

特殊情况

  1. 链表为空或只有一个节点
  2. k 的值为 0 或者为链表长度 L 的整数倍(N > 0)

一般情况

  1. 链表至少有两个节点且 k 既不等于 0 也不等于 L 的整数倍。

思路

  • 特殊情况
  1. 链表为空或只有一个节点,返回头节点即可
  2. 判断 k == 0,如果等于 0,则直接返回头节点,否则求链表长度 L,再判断 k == NL,如果等于,也可直接返回头节点。
  • 一般情况
  1. 采用 虚拟头节点 + 双指针 的方法,具体如下栗子分析。
举栗

以链表 1->2->3->4->5,k = 2 为栗,如下图示。

  1. 增加虚拟头节点,并让两个快慢指针指向它;
  1. 先让快指针 fast 向前移动 k 步慢指针 slow 保持不动
  1. 快慢指针 fast/slow 同时向前移动,直至快指针指向尾节点
  1. 快指针 fast 指向的节点指向链表的头节点,使链表成环;
  1. 将慢指针 slow 指向的节点的下一节点设置为新链表的头节点
  1. 将慢指针 slow 指向的节点设置为新链表的尾节点 slow->next = null
  1. 旋转原链表后得到新链表。
完整动图

反思

  1. 如何找到旋转之后得到的新链表的头节点?

采用 双指针 中的 快慢指针

  1. 设置虚拟头节点的作用?

本题设置 虚拟头节点 的作用是找到 新链表的头节点和尾节点。通过 快慢指针 去寻找。

Show me the Code

C++
代码语言:javascript
复制
ListNode* rotateRight(ListNode* head, int k) {
    /*  特殊情况判断  */
    if (head == nullptr || head->next == nullptr || k == 0) {
        return head;
    }

    /*  增加虚拟头节点  */
    ListNode* dummy = new ListNode(0);
    dummy->next = head;

    /*  获取链表长度  */
    int len = 0;
    for (ListNode* node = head; node != nullptr; node = node->next) {
        len++;
    }

    k %= len;
    /*  判断 k 是否是 len 的整数倍  */
    if (k == 0) {
        return head;
    }

    /*  获取新链表的头尾节点  */
    ListNode *fast = dummy, *slow = dummy;
    for (int i = 0; i < k; ++i) {
        fast = fast->next;
    } 
    while (fast->next != nullptr) {
        fast = fast->next;
        slow = slow->next;   
    }        
    fast->next = head; 
    head = slow->next; 
    slow->next = nullptr;

    /*  释放虚拟头节点  */
    delete dummy;
    
    return head;
}
java
代码语言:javascript
复制
ListNode rotateRight(ListNode head, int k) {
    if (k == 0 || head == null || head.next == null) {
        return head;
    }

    ListNode dummy = new ListNode(0);
    dummy.next = head;

    int len = 0;
    for (ListNode node = head; node != null; node = node.next) {
        len++;
    }     

    k %= len;
    if (k == 0) {
        return head;
    }

    ListNode fast = dummy, slow = dummy;
    for (int i = 0; i < k; ++i) {
        fast = fast.next;
    } 
    while (fast.next != null) {
        fast = fast.next;
        slow = slow.next;   
    }        
    fast.next = head; 
    head = slow.next; 
    slow.next = null;

    return head;
}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员小熊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 61. 旋转链表
    • 解题思路
      • Show me the Code
        • C++
        • java
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档