C语言每日一题(43)旋转链表

力扣 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

思路分析

最开始的时候我是尝试过截断法的,就是每旋转一次,就将后面的结点指向头结点并把前面的结点的指针截断置空,但后面调试发现,这只适用于旋转一次,因为旋转后,新的尾结点的前驱结点找不到了,就算实现了,时间复杂度O(n2)也挺高的。

后面我发现了一种思路,也是截断法,但不同的在于它是一次性截完,我们之前写过一题,找出链表的倒数第N个结点,比如说n=2,当我们找到了倒数第二个结点时,我们发现,该节点后面的所有结点不就是我们所需要旋转的结点吗,我们就没必要一个个截断,找到所有需要旋转的点一次性截断就行了。

关于快慢指针走的步数,题目给的值万一很大就会超出时间限制,其实我们之前写过关于字符串的旋转,当旋转次数等于字符串长度时,等于没旋转,记得将次数模一下链表长度再进循环。

复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* rotateRight(struct ListNode* head, int k) {
   struct ListNode* tail=head;//快指针
   struct ListNode* prev=head;//慢指针
   struct ListNode* cur=head;//记录链表长度
   int n=0;

   if(k==0||head==NULL||head->next==NULL)
   {
       return head;
   }
   while(cur)
   {
       n++;
       cur=cur->next;//计算链表长度

   }
   k=k%n;//记得模一下
//找需要截断的结点位置
   while(k--)
   {
       if(tail->next==NULL)
       {
           tail=head;
       }
       else
       {
           tail=tail->next;
       }
   }
   while(tail->next)
   {
       tail=tail->next;
       prev=prev->next;
   }
//截断
   tail->next=head;//将末尾结点指向头结点
   head=prev->next;//头结点移动到prev的下一个成为新头节点
   prev->next=NULL;//截断prev和tail,prev成为链表尾结点
   
   
   return head;
    
}
相关推荐
biter down6 小时前
14:pytest-order 插件 顺序控制案例
开发语言·python·pytest
郝学胜-神的一滴6 小时前
Qt 高级开发 009: C++ Lambda 表达式
开发语言·c++·qt·软件构建
星栈独行6 小时前
我在 Rust 全栈项目里用 JWT 做无状态认证
开发语言·后端·rust·前端框架·开源·github·web
石山代码7 小时前
C++ 轻量级日志系统
开发语言·c++
小技与小术7 小时前
玩转Flask
开发语言·python·flask
SilentSamsara7 小时前
Python 性能优化:tracemalloc、profiling 与 C 扩展加速
开发语言·python·青少年编程·性能优化
冰小忆7 小时前
大驼峰命名规范和小驼峰命名规范的区别是什么?
开发语言·python
冉卓电子9 小时前
MPC5604B/C eMIOS 高级定时器全解
c语言
এ慕ོ冬℘゜9 小时前
JS 前端基础面试题
开发语言·前端·javascript
浩少7029 小时前
【无标题】
java·开发语言