• 力扣 61. 旋转链表


    目录

    第一站 LeetCode 新手村

    前言

    61. 旋转链表

    题目描述

    解题思路

    代码

    总结

    题目来源


    第一站 LeetCode 新手村


    前言

    最近玩OJ赛,发现对算法的理解还需要更加扎实,code能力还可以进一步提升,所以做这样一个算法的系列文章,用于记录学习心得,交流经验,更好地进步和成长。


    61. 旋转链表

    题目描述

    给你一个链表的头节点 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]
    

    提示

    • 链表中节点的数目在范围 [0, 500] 内
    • -100 <= Node.val <= 100
    • 0 <= k <= 2 * 109

    解题思路

    预知

    LeetCode是核心代码模式,所以只需要考虑核心算法,输入由系统自动完成,最后的输出以return返回;

    思路

    这道题虽然是旋转链表,但实际上是将原链表队尾的k个节点,接到队首,也即,将倒数第k个结点变为新的队首,倒数第k+1个结点变为新的队尾;

    也可以理解为,保留原链表的前len-k个元素(此处的len是链表长度),然后将第len-k个元素变为链表的新的队尾,第len-k+1个元素变为新的链表的队首;

    具体的实现思路可以参考代码和注释;

    由于没有用到新的空间,只需要遍历两次链表,时间复杂度为O(N+N),可以理解为O(N)

    代码

    C++ 

    非注释版本,看起来更整洁,往下滑,下面有注释版本

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * ListNode *next;
    6. * ListNode() : val(0), next(nullptr) {}
    7. * ListNode(int x) : val(x), next(nullptr) {}
    8. * ListNode(int x, ListNode *next) : val(x), next(next) {}
    9. * };
    10. */
    11. class Solution {
    12. public:
    13. ListNode* rotateRight(ListNode* head, int k) {
    14. ListNode* cur = head;
    15. if(!head || !head->next) return head;
    16. int len = 1;
    17. while(cur->next){
    18. cur = cur->next;
    19. len++;
    20. }
    21. k = k%len;
    22. if(k==0) return head;
    23. k = len-k;
    24. cur->next = head;
    25. cur = new ListNode(0,head);
    26. while(k--){
    27. cur = cur->next;
    28. }
    29. ListNode* newhead = nullptr;
    30. newhead = cur->next;
    31. cur->next = nullptr;
    32. return newhead;
    33. }
    34. };

    注释版本 

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * ListNode *next;
    6. * ListNode() : val(0), next(nullptr) {}
    7. * ListNode(int x) : val(x), next(nullptr) {}
    8. * ListNode(int x, ListNode *next) : val(x), next(next) {}
    9. * };
    10. */
    11. class Solution { //巧妙使用程序顺序执行来实现
    12. public:
    13. ListNode* rotateRight(ListNode* head, int k) {
    14. ListNode* cur = head; //定义一个工具结点,用于遍历整个链表
    15. if(!head || !head->next) return head; //如果链表为空,或者只有一个结点则直接返回该链表
    16. int len = 1; //用于记录链表的长度,
    17. while(cur->next){ //统计链表长度,并找到队尾元素(也是用while的条件用cur->next,而不用cur的原因),以便后续操作
    18. cur = cur->next;
    19. len++;
    20. }
    21. k = k%len; //对k值和链表的长度进行取余,防止超时;
    22. if(k==0) return head; //没移动,直接返回原链表
    23. k = len-k; //找到正数的第len-k个结点的位置即可
    24. cur->next = head; //此时的cur还处于尾结点,让它指向头节点,构成连续的链表,一会儿在新的头结点断开即可
    25. cur = new ListNode(0,head); //哑结点,从哑结点开始遍历,刚好可以找到正数第len-k个元素
    26. while(k--){ //开始寻找正数第len-k个元素
    27. cur = cur->next;
    28. }
    29. ListNode* newhead = nullptr; //用于记录新的头结点
    30. newhead = cur->next; //正数第len-k个元素的下一个就是新的头结点
    31. cur->next = nullptr; //将正数第len-k个元素的下一结点指向空
    32. return newhead;
    33. }
    34. };


    总结

    以上就是今天要讲的内容,本文仅仅简单讲解了《力扣 61. 旋转链表》这一题目,是自主解答且通过的一次尝试。

    题目来源

    来源:力扣(LeetCode)
    链接:力扣

  • 相关阅读:
    【大学英语视听说上】课后主题作文
    算法补天系列之有序表的四种实现方式——AVL树,SB树,红黑树,跳表(重点)介绍说明
    Matlab多维数组漫谈教程
    【Linux】Linux环境基础开发工具使用
    React技术栈 --》plugin与JSX语法使用 ## Day2
    .Net6使用WebSocket与前端进行通信
    某汽车金融企业:搭建SDLC安全体系,打造智慧金融服务样本
    关于安装ubuntu 18.06.6 系统时出现[Errno 5] - Input/output error 错误的解决方案
    odoo javascript参考(六)
    计算机组成与体系结构入门(二)
  • 原文地址:https://blog.csdn.net/m0_51787573/article/details/127739324