当前位置: 首页 > news >正文

61.旋转链表--字节跳动

你应该比你现在强得多

题目描述

给定单链表,要求返回向右移动K位后的新链表

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

思路分析

  1. 计算链表的长度

  2. 计算实际需要移动的步数

  3. 找到新的头节点

  4. 断开链表并重新连接

完整代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        // 边界条件检查:如果链表为空、只有一个节点或 k 为 0,直接返回原链表
        if (head==NULL || head->next==NULL || k == 0) {
            return head;
        }

        // 1. 计算链表的长度
        int n = 1; // 链表长度初始化为 1,因为从第一个节点开始
        ListNode* tail = head; // tail 指针用于找到链表的末尾节点
        while (tail->next) { // 遍历链表直到最后一个节点
            tail = tail->next; // 移动到下一个节点
            n++; // 计数器增加
        }

        // 2. 计算实际需要移动的步数
        k = k % n; // k 对链表长度取模,避免不必要的重复旋转
        if (k == 0) {
            return head; // 如果 k 为 0,说明不需要旋转,直接返回原链表
        }

        // 3. 找到新的头节点
        ListNode* newTail = head; // newTail 指针用于找到旋转后新的尾节点
        for (int i = 0; i < n - k - 1; i++) { // 移动到新尾节点的位置(n - k - 1)
            newTail = newTail->next; // 移动到下一个节点
        }
        ListNode* newHead = newTail->next; // 新头节点是新尾节点的下一个节点

        // 4. 断开链表并重新连接
        newTail->next = nullptr; // 断开新尾节点与新头节点的连接
        tail->next = head; // 将原链表的尾节点连接到原链表的头节点,形成环

        return newHead; // 返回旋转后的新头节点
    }
};

分析逻辑

1. 边界条件检查

  • 如果链表为空(head==NULL),或者链表只有一个节点(head->next==NULL),或者 k 为 0,直接返回原链表。

  • 这些情况下链表不需要进行任何旋转操作。

2. 计算链表长度

  • 使用 tail 指针从链表头开始遍历,直到链表的末尾(tail->nextnullptr)。

  • 在遍历过程中,计数器 n 记录链表的长度。

3. 计算实际移动步数

  • 由于旋转 k 次相当于旋转 k % n 次,因为旋转 n 次后链表会回到原来的状态。

  • 如果 k % n == 0,说明不需要旋转,直接返回原链表。

4. 找到新的头节点

  • 使用 newTail 指针从链表头开始,移动 n - k - 1 步,到达旋转后的新尾节点。

  • newTail->next 就是旋转后的新头节点。

5. 断开链表并重新连接

  • 将新尾节点 (newTail) 的 next 指针设为 nullptr,断开与新头节点的连接。

  • 将原链表的尾节点 (tail) 的 next 指针指向原链表的头节点 (head),形成一个新的链表环。

  • 返回新的头节点 newHead,完成链表的旋转操作。

总结

  • 该算法通过计算链表长度和实际旋转步数,找到新的头节点和尾节点,并重新连接链表,实现链表的右旋转。

  • 时间复杂度为 O(n),空间复杂度为O(1) 。

相关文章:

  • Redisson分布式锁java语法, 可重入性实现原理 ,(还有可重试性,超时不释放,主从一致性)
  • 第16届蓝桥杯模拟赛3 python组个人题解
  • mysql之规则优化器RBO
  • 抽象类、接口、枚举
  • rust 安全性
  • PiscTrace开发者版:只需考虑算法的视图处理应用
  • python绘制年平均海表温度、盐度、ph分布图
  • TTRSS 迁移实战
  • 通过阿里百炼配置自己的------AI 智能英语陪练
  • springboot系列十四: 注入Servlet, Filter, Listener + 内置Tomcat配置和切换 + 数据库操作
  • 程序员本地网站(WEB)
  • 政安晨【零基础玩转各类开源AI项目】DeepSeek 多模态大模型Janus-Pro-7B,本地部署!支持图像识别和图像生成
  • 数据链路层有给用户可操作的接口吗
  • Docker国内镜像源部署deepseek
  • [MDM 2024]Spatial-Temporal Large Language Model for Traffic Prediction
  • Vite 和 Webpack 的区别和选择
  • 项目自荐:一个实用的免费批量文档翻译器
  • 【爬虫基础】第一部分 网络通讯-编程 P3/3
  • 快速熟悉商城源码的架构、业务逻辑和技术框架
  • 跟着AI学vue第八章
  • 宇数科技王兴兴:第一桶金来自上海,欢迎上海的年轻人加入
  • 视频丨雄姿英发!中国仪仗队步入莫斯科红场
  • 山东14家城商行中,仅剩枣庄银行年营业收入不足10亿
  • 国家主席习近平在莫斯科出席红场阅兵式
  • 调节负面情绪可以缓解慢性疼痛
  • 司法部:持续规范行政执法行为,加快制定行政执法监督条例