【C语言】字符串左旋的三种解题方法详细分析


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C语言

文章目录

  • 💯前言
  • 💯题目描述
  • 💯方法一:逐字符移动法
  • 💯方法二:使用辅助空间法
  • 💯方法三:三次反转法
  • 💯方法对比与总结
    • 拓展思考
  • 💯总结

在这里插入图片描述


在这里插入图片描述


💯前言

  • 在这篇文章中,我们将深入探讨字符串左旋的三种解决方案,系统分析每种方法的算法设计时间复杂度空间复杂度,以及其适用场景局限性。这些方法从简单到高效,分别展示了逐字符移动法使用辅助空间法三次反转法的不同特点及其理论基础
    通过对这些方法的详细对比讨论,读者将对字符串操作基本原理有更为深入的理解,掌握在不同应用场景下如何选择最优的解决方案,以提升代码的效率鲁棒性
    C语言
    在这里插入图片描述

💯题目描述

实现一个函数,能够左旋字符串中的 k 个字符。

例如:

  • 给定字符串 ABCD,如果左旋 1 个字符,得到 BCDA
  • 如果左旋 2 个字符,得到 CDAB

左旋是指将字符串的前面部分字符移到字符串的末尾。我们将使用三种不同的实现方式来解决这一问题:逐字符移动法、使用辅助空间法、以及三次反转法。


💯方法一:逐字符移动法

思路

逐字符移动法是一种直观的实现方式,通过多次迭代将字符串的第一个字符移动到末尾,直到完成所需的旋转次数。该方法依赖于不断移动字符的位置以达到最终目标。其本质是一种线性搬移操作,容易理解,但在大数据量的情况下效率较低。
在这里插入图片描述

代码实现

void leftRound(char* str, int k) {int len = strlen(str);int time = k % len;for (int i = 0; i < time; i++) {char tmp = str[0];int j = 0;for (; j < len - 1; j++) {str[j] = str[j + 1];}str[j] = tmp;}
}int main() {char str[] = "abcdef";leftRound(str, 7);printf("%s\n", str);return 0;
}

解释

  • 获取字符串长度 len
  • 计算实际旋转次数 time = k % len,这样可以避免 k 超过字符串长度导致的冗余操作。
  • 外层循环用于执行 time 次旋转,每次只移动一个字符。
  • 使用内部的 for 循环,将每个字符依次前移一个位置,最后将原来的第一个字符移到末尾。

时间复杂度和空间复杂度

  • 时间复杂度:O(k * len),对于每次旋转都需要遍历整个字符串,因而效率较低。
  • 空间复杂度:O(1),只需一个额外的字符变量来暂存被移动的字符。

优缺点

  • 这种方法的优点是实现简单且易于理解,适合初学者用于理解字符串旋转的基本概念。但其缺点在于效率较低,尤其在 k 较大和字符串长度较长时,由于需要多次逐字符移动,时间开销会显著增加。

💯方法二:使用辅助空间法

思路

使用辅助空间法通过将旋转后的字符串临时保存,再将结果复制回原字符串。借助辅助空间将两个部分拼接,可以有效避免逐字符移动带来的低效问题。该方法的核心在于利用辅助数组,快速完成字符串的局部重组与合并
在这里插入图片描述

代码实现

void leftRound(char* str, int k) {int len = strlen(str);int time = k % len;char tmp[256] = { 0 };strcpy(tmp, str + time); strncat(tmp, str, time); strcpy(str, tmp);
}int main() {char str[] = "abcdef";leftRound(str, 7);printf("%s\n", str);return 0;
}

解释

  • 通过 strlen 获取字符串的长度。
  • 计算实际的旋转次数 time = k % len,以应对 k 过大时的情况。
  • 使用临时数组 tmp 存储旋转后的结果。
  • 利用 strcpy 函数将原字符串从 time 索引位置开始的部分复制到 tmp 中。
    • strcpy(tmp, str + time)str + time 表示指向原字符串从第 time 个位置开始的指针,strcpy 函数将从这个位置开始的所有字符(直到字符串结束符 )复制到 tmp 中。因此,tmp 中最初会存储字符串的后半部分。例如,若 str = "ABCD"time = 2strcpy(tmp, str + time)"CD" 复制到 tmp,结果为 tmp = "CD"
  • 使用 strncat 函数将原字符串的前 time 个字符拼接到 tmp 的末尾。
    • strncat(tmp, str, time)strncat 用于将源字符串的指定数量字符拼接到目标字符串的末尾。在这里,str 表示原字符串,time 表示从 str 开头开始的 time 个字符。因此,strncat(tmp, str, time) 将原字符串的前 time 个字符(即 "AB")拼接到 tmp 的末尾,形成最终结果。例如,当 tmp = "CD"time = 2 时,拼接后结果为 tmp = "CDAB"
  • 最后使用 strcpytmp 的内容复制回原字符串 str,完成旋转操作。

时间复杂度和空间复杂度

  • 时间复杂度:O(n),只需遍历字符串几次即可完成旋转。
  • 空间复杂度:O(n),需要额外的存储空间来保存旋转后的结果。

优缺点

  • 辅助空间法的优势在于其高效的操作,尤其适合处理较大的字符串,但需要额外的空间来存储结果。因此,对于内存资源受限的情况,该方法可能不太适合。

💯方法三:三次反转法

思路

三次反转法通过对字符串的部分片段进行反转,从而达到整体左旋的效果。核心思想是将字符串划分为两部分,分别反转,再对整体反转,以实现最终的左旋

这种方法以极少的操作步骤完成字符位置的重新排列,具有较高的效率数学美感

在这里插入图片描述

代码实现

void ReverseRange(char* str, int start, int end) {int left = start;int right = end;while (left < right) {char tmp = str[left];str[left] = str[right];str[right] = tmp;left++;right--;}
}void leftRound(char* str, int k) {int len = strlen(str);int time = k % len;ReverseRange(str, 0, time - 1);    // 反转前 time 个字符ReverseRange(str, time, len - 1);  // 反转剩余部分ReverseRange(str, 0, len - 1);     // 反转整个字符串
}int main() {char str[] = "abcdef";leftRound(str, 7);printf("%s\n", str);return 0;
}

解释

  1. 反转前 time 个字符

    • 调用 ReverseRange(str, 0, time - 1),反转字符串的前 time 个字符。
    • 例如,对 "ABCD" 反转前两个字符,得到 "BACD"
  2. 反转剩余部分

    • 调用 ReverseRange(str, time, len - 1),反转剩余部分。
    • "BACD" 中的后两个字符反转,得到 "BADC"
  3. 反转整个字符串

    • 调用 ReverseRange(str, 0, len - 1),反转整个字符串。
    • "BADC" 反转得到 "CDAB",从而完成左旋操作。

时间复杂度和空间复杂度

  • 时间复杂度:O(n),三次反转操作均为线性时间复杂度,因此总时间复杂度为 O(n)
  • 空间复杂度:O(1),只需进行交换操作,没有额外的空间开销。

优缺点

  • 三次反转法的优势在于其高效性,时间复杂度为 O(n),空间复杂度为 O(1),适合处理大规模字符串。该方法通过反转实现字符串的重新排列,以最小的时间和空间成本实现左旋,非常适合实际开发中的高效实现。

💯方法对比与总结

方法时间复杂度空间复杂度优点缺点
逐字符移动法O(k * n)O(1)实现简单,直观效率较低
辅助空间法O(n)O(n)实现高效,代码简洁需要额外空间
三次反转法O(n)O(1)高效且无额外空间开销实现稍复杂,需要三次反转
  • 逐字符移动法 适合初学者理解字符串旋转的概念,但效率不高。在字符较多或者旋转次数较大时,可能会因为需要逐次移动而显得低效
  • 辅助空间法 则通过一次性拼接字符串提升了效率,但需要额外的空间存储,对于空间资源紧张的场景可能不适合
  • 三次反转法最优的方法,尤其适合大规模字符串。它的空间复杂度最低效率高,是一个非常经典的字符串操作技巧。该方法不仅巧妙而且具有一定的数学美感,通过三次反转将字符串重新排列到目标位置。

拓展思考

  • 这些字符串旋转的实现方法可以拓展到其他类型的数据结构,例如数组的左旋、右旋操作。对于数组来说,三次反转法同样有效,可以通过类似的思路对数组元素进行重新排列。
  • 三次反转法的思想不仅可以用于字符串旋转,还可以用于链表数组等其他序列的数据结构。它是一种通用的思想,可以帮助解决许多涉及顺序调整的问题。
  • 对于多种编程语言,我们也可以找到相似的实现方法。Python 中可以使用字符串切片操作来轻松实现左旋,而 Java 中可以借助 StringBuilder 进行高效的字符串操作。Python 的切片方法非常直观,例如可以使用 s = s[k:] + s[:k] 来实现左旋操作,简洁而高效。
  • 对于面试场景,理解这些方法的时间复杂度空间复杂度,以及不同方法在实际应用中的适用性非常重要。面试官通常希望看到你对基础方法的掌握以及对最优解法的深入理解。

💯总结

  • 在这里插入图片描述
    字符串左旋是一个非常基础但又非常经典的字符串操作问题。通过这篇文章的深入解读,我们详细探讨了三种不同的解决方案,并对每种方法的算法复杂度适用场景优缺点进行了深入分析。掌握这些方法有助于我们在面试中应对字符串操作类的问题,也能帮助我们在实际开发中写出更优雅、高效的代码。这三种方法展示了从基础到高效的不同解决思路,是学习和掌握字符串操作的宝贵经验
    希望这篇文章能够激发你对字符串操作的更深入思考与理解。未来的学习和工作中,愿你能够灵活应用这些技巧,优化代码的效率与可读性,深入理解不同方法背后的原理,并能够在解决问题时选择最合适的工具。这正是编程的艺术,也是不断提升的动力所在

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/62020.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大模型】LLaMA-Factory的环境配置、微调模型与测试

前言 【一些闲扯】 时常和朋友闲聊&#xff0c;时代发展这么快&#xff0c;在时代的洪流下&#xff0c;我们个人能抓住些什么呢。我问了大模型&#xff0c;文心一言是这样回答的&#xff1a; 在快速发展的时代背景下&#xff0c;个人确实面临着诸多挑战&#xff0c;但同时也充满…

Web 表单开发全解析:从基础到高级掌握 HTML 表单设计

文章目录 前言一、什么是 Web 表单?二、表单元素详解总结前言 在现代 Web 开发中,表单 是用户与后端服务交互的重要桥梁。无论是用户登录、注册、搜索,还是提交反馈,表单都无处不在。在本文中,我们将从基础入手,全面解析表单的核心知识点,并通过示例带你轻松掌握表单开…

nodepad配置c/c++ cmd快速打开创建项目文件

前提:下载MinGw,并且配置环境变量 点击阅读次篇文章配置MinGw 无论是哪个编译器&#xff0c;执行c文件都是经历以下步骤: 编译文件生成exe文件执行该exe文件 我们先手动完成这两部 手动编译文件使用指令 gcc {你的c文件} -o {生成文件名}生成exe文件 第二步运行exe直接点击该文…

打造优秀技术文档的三大方向

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Xcode15(iOS17.4)打包的项目在 iOS12 系统上启动崩溃

0x00 启动崩溃 崩溃日志&#xff0c;只有 2 行&#xff0c;看不出啥来。 0x01 默认配置 由于我开发时&#xff0c;使用的 Xcode 14.1&#xff0c;打包在另外一台电脑 Xcode 15.3 Xcode 14.1 Build Settings -> Asset Catalog Compliter - Options Xcode 15.3 Build S…

如何使用GCC手动编译stm32程序

如何不使用任何IDE&#xff08;集成开发环境&#xff09;编译stm32程序? 集成开发环境将编辑器、编译器、链接器、调试器等开发工具集成在一个统一的软件中&#xff0c;使得开发人员可以更加简单、高效地完成软件开发过程。如果我们不使用KEIL,IAR等集成开发环境&#xff0c;…

QUICK 调试camera-xml解析

本文主要介绍如何在QUICK QCS6490使能相机模组。QCS6490的相机基于CameraX的框架&#xff0c;只需通过配置XML文件&#xff0c;设置相机模组的相关参数&#xff0c;就可以点亮相机。本文主要介绍Camera Sensor Module XML和Camera Sensor XML配置的解析&#xff0c;这中间需要c…

数据结构 (11)串的基本概念

一、串的定义 1.串是由一个或者多个字符组成的有限序列&#xff0c;一般记为&#xff1a;sa1a2…an&#xff08;n≥0&#xff09;。其中&#xff0c;s是串的名称&#xff0c;用单括号括起来的字符序列是串的值&#xff1b;ai&#xff08;1≤i≤n&#xff09;可以是字母、数字或…

汽车渲染领域:Blender 和 UE5 哪款更适用?两者区别?

在汽车渲染领域&#xff0c;选择合适的工具对于实现高质量的视觉效果至关重要。Blender和UE5&#xff08;Unreal Engine 5&#xff09;作为两大主流3D软件&#xff0c;各自在渲染动画方面有着显著的差异。本文将从核心定位与用途、工作流程、渲染技术和灵活性、后期处理与合成四…

开源加密库mbedtls及其Windows编译库

目录 1 项目简介 2 功能特性 3 性能优势 4 平台兼容性 5 应用场景 6 特点 7 Windows编译 8 编译静态库及其测试示例下载 1 项目简介 Mbed TLS是一个由ARM Maintained的开源项目&#xff0c;它提供了一个轻量级的加密库&#xff0c;适用于嵌入式系统和物联网设备。这个项…

C语言数据结构——详细讲解 双链表

从单链表到双链表&#xff1a;数据结构的演进与优化 前言一、单链表回顾二、单链表的局限性三、什么是双链表四、双链表的优势1.双向遍历2.不带头双链表的用途3.带头双链表的用途 五、双链表的操作双链表的插入操作&#xff08;一&#xff09;双链表的尾插操作&#xff08;二&a…

MYSQL 表的增删改查(上)

目录 1.新增数据 2.查询数据 一般查询 去重查询 排序查询 关于NULL 条件查询 分页查询 1.新增数据 语法&#xff1a;insert into 表名[(字段1&#xff0c;字段2...)] values (值&#xff0c;值....); 插入一条新数据行&#xff0c;前面指定的列&#xff0c;要与后面v…

Docker pull镜像拉取失败

因为一些原因&#xff0c;很多镜像仓库拉取镜像失败&#xff0c;所以需要更换不同的镜像&#xff0c;这是2024/11/25测试可用的仓库。 标题1、 更换镜像仓库的地址&#xff0c;编辑daemon.json文件 vi /etc/docker/daemon.json标题2、然后将下面的镜像源放进去或替换掉都可以…

C语言学习 12(指针学习1)

一.内存和地址 1.内存 在讲内存和地址之前&#xff0c;我们想有个⽣活中的案例&#xff1a; 假设有⼀栋宿舍楼&#xff0c;把你放在楼⾥&#xff0c;楼上有100个房间&#xff0c;但是房间没有编号&#xff0c;你的⼀个朋友来找你玩&#xff0c;如果想找到你&#xff0c;就得挨…

VITE+VUE3+TS环境搭建

前言&#xff08;与搭建项目无关&#xff09;&#xff1a; 可以安装一个node管理工具&#xff0c;比如nvm&#xff0c;这样可以顺畅的切换vue2和vue3项目&#xff0c;以免出现项目跑不起来的窘境。我使用的nvm&#xff0c;当前node 22.11.0 目录 搭建项目 添加状态管理库&…

Zookeeper选举算法与提案处理概览

共识算法(Consensus Algorithm) 共识算法即在分布式系统中节点达成共识的算法&#xff0c;提高系统在分布式环境下的容错性。 依据系统对故障组件的容错能力可分为&#xff1a; 崩溃容错协议(Crash Fault Tolerant, CFT) : 无恶意行为&#xff0c;如进程崩溃&#xff0c;只要…

ffmpeg视频滤镜:提取缩略图-framestep

滤镜描述 官网地址 > FFmpeg Filters Documentation 这个滤镜会间隔N帧抽取一帧图片&#xff0c;因此这个可以用于设置视频的缩略图。总体上这个滤镜比较简单。 滤镜使用 滤镜参数 framestep AVOptions:step <int> ..FV....... set frame st…

微服务篇-深入了解使用 RestTemplate 远程调用、Nacos 注册中心基本原理与使用、OpenFeign 的基本使用

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 认识微服务 1.1 单体架构 1.2 微服务 1.3 SpringCloud 框架 2.0 服务调用 2.1 RestTemplate 远程调用 3.0 服务注册和发现 3.1 注册中心原理 3.2 Nacos 注册中心 …

TCP/IP学习笔记

TCP\IP从实际应用的五层结构开始&#xff0c;自顶而下的去分析每一层。 TCP/IP五层架构概述 学术上面是TCP/IP四层架构&#xff0c;OSI/ISO是七层架构&#xff0c;实际中使用的是TCP/IP五层架构。 数据链路层 ICMP数据包分析 Wireshark抓包分析ICMP协议_wireshark抓ping包分析…

互联网视频推拉流EasyDSS视频直播点播平台视频转码有哪些技术特点和应用?

视频转码本质上是一个先解码再编码的过程。在转码过程中&#xff0c;原始视频码流首先被解码成原始图像数据&#xff0c;然后再根据目标编码标准、分辨率、帧率、码率等参数重新进行编码。这样&#xff0c;转换前后的码流可能遵循相同的视频编码标准&#xff0c;也可能不遵循。…