剑指offer系列——剑指 Offer 58 - II. 左旋转字符串(C/C++/Java语言)

本文介绍了如何实现字符串的左旋转操作,讲解了三种不同的解题思路:暴力遍历、巧妙拷贝和逆序三部曲。详细讨论了每种方法的时间复杂度,并提供了C/C++/Java语言的源代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

⭐️前面的话⭐️

大家好!博主开辟了一个新的专栏——剑指offer,我要开始刷题了!这个专栏会介绍《剑指offer》书上所有的面试编程题。并且会分享一些我的刷题心得。由于博主水平有限,如有错误,欢迎指正,如果有更好的解题思路和算法可以分享给博主哦!一起加油!一起努力!

📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2021年9月10日🌴
💖祝所有的老师教师节快乐!💖
✉️坚持和努力一定能换来诗与远方!
💭参考书籍:📚《剑指offer第1版》,📚《剑指offer第2版》
💬参考在线编程网站:🌐牛客网🌐力扣
🙏作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
博主的码云gitee,平常博主写的程序代码都在里面。



⭐️剑指 Offer 58 - II. 左旋转字符串⭐️

🔐题目详情

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例:

输入: s = "abcdefg", k = 2
输出: "cdefgab"
输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"

限制:

1 <= k < s.length <= 10000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof

💡解题思路

在正式对字符串进行左旋之前,首先来看看字符串左旋次数与字符串个数的规律,假设字符串长度为len, 左旋次数为k。举例一个字符串str=abcdef,此时len = 6,当k=1,左旋得bcdefak=3,左旋得defabck=6,左旋得abcdef与初始时的字符串相等,所以我们可以通过规律得到左旋次数k为字符串长度len的倍数时,左旋字符串与初始时字符串相同,所以说,当左旋len+1次与左旋1次的效果是相同的,所以在对字符串进行左旋操作时不妨先对左旋次数klen的模,这样,当k比较大时,消耗的时间比较少,提高了程序的效率!
由于力扣平台提供的字符串指针常量,不能对该指针指向的内容进行修改,需要自己申请空间进行字符串的左旋操作!
方法1: 暴力遍历。
我们最先想到的就是遍历,每次左旋,我们就将第一个字符替换到最后一个字符位置,并将后面的字符左移。
11

时间复杂度: O(k*N)

对于暴力模拟算法,我门可以做一点优化,那就是我们可以将两段原字符串拼在一起,不妨设原字符串长度为m, 那么下标为m+j对应的字符相当于下标为j的字符串。
12

那么左旋n次,等同于左旋k=n%m次,就是俩段合并字符串中的[k, k + m - 1]区间的字符串。

方法2: 巧妙拷贝。
申请好内存之后,我们可以对原字符串s进行特定位置的拷贝,比如字符串abcdefg需要左旋该字符串k次,该字符串长度为len=7,不难发现下标为k%len的字符,左旋k次后,会在数组的首位置,所以我们可以从原字符串下标为 k % l e n k\%len k%len字符开始拷贝。

但是注意要保证k的值不大于字符串长度len(先对klen的模,即k %= len),由于访问拷贝完最后一个元素后需要访问拷贝首个元素,所以我们需要对访问的数组下标取len的模(即*(s+(k+i)%len)s[(k+i)%len])保证数组不越界和实现从最后一个元素过渡到首个元素,该栗子中数组下标顺序为k->k+1->...->len-1->0->...->k-1,如果k=4,进行拷贝的数组下标次序是4->5->6->0->1->2->3,得到的就是逆序的字符串efgabcd
22

时间复杂度: O(N)
方法3: 逆序三部曲。
还是以字符串abcdefg需要左旋该字符串k次(保证k < len),该字符串长度为len=7,左旋次数k=4为例!
因为下标为k%len的字符,左旋k次后,会在数组的首位置,所以我以该元素为分界线,位于该元素之前的作为一组(不包括该分界字符),下标范围为 [ 0 , k % l e n − 1 ] [0,k\%len-1] [0,k%len1],位于该元素之后的作为一组(包含该分界字符),下标范围为 [ k % l e n , l e n − 1 ] [k\%len,len-1] [k%len,len1]
先分别对两部分进行逆序,然后在整个字符串进行逆序,就能得到左旋k次的字符串,一共进行三次字符串逆序,简称“逆序三部曲”。
33

时间复杂度: O(N)

🔑源代码

编程语言:C语言/C++/Java
在线编程平台:力扣

C语言:

//方法1
char* reverseLeftWords(char* s, int n){
   
   
	int len = strlen(s);
    int k = 0;
    k = n % len;//当左旋位数为字符串长度整数倍时,左旋后与初始相同
    int i = 0;
    char* str = (char*)malloc(sizeof(char) * len + 1) <
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未见花闻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值