题目
链接
https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/
说明
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串abcdefg
和数字2
,该函数将返回左旋转两位得到的结果cdefgab
。
示例 1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:
输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
限制:
- 1 ≤ k < s . l e n g t h ≤ 10000 1 \leq k < s.length \leq 10000 1≤k<s.length≤10000
解题
解题思路:
本题做法较多,本文主要介绍 “字符串切片” , “列表遍历拼接” , “字符串遍历拼接” 三种方法。
由于本题的多解法涉及到了 字符串为不可变对象 的相关概念,导致效率区别较大。因此,单列一节 三种方法的效率分析 ,望对各位有所帮助。
方法一:字符串切片
应用字符串切片函数,可方便实现左旋转字符串。
获取字符串 s [ n : ] s[n:] s[n:] 切片和 s [ : n ] s[:n] s[:n] 切片,使用 + + ++ ++运算符拼接并返回即可。
复杂度分析:
- 时间复杂度 O ( N ) O(N) O(N) : 其中 N N N 为字符串 s s s 的长度,字符串切片函数为线性时间复杂度(参考资料);
- 空间复杂度 O ( N ) O(N) O(N) : 两个字符串切片的总长度为 N N N 。
代码
Python
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
return s[n:] + s[:n]
方法二:列表遍历拼接
若面试规定不允许使用 切片函数 ,则使用此方法。
算法流程:
- 新建一个
list(Python)
、StringBuilder(Java)
,记为resres
; - 先向
resres
添加 “第 n + 1 n + 1 n+1 位至末位的字符” ; - 再向
resres
添加 “首位至第 n n n 位的字符” ; - 将
resres
转化为字符串并返回。
复杂度分析:
- 时间复杂度 O ( N ) O(N) O(N) : 线性遍历 s s s并添加,使用线性时间;
- 空间复杂度
O
(
N
)
O(N)
O(N) : 新建的辅助
r
e
s
r
e
s
resres
resres 使用
O
(
N
)
O(N)
O(N) 大小的额外空间。
代码
python
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
res = []
for i in range(n, len(s)):
res.append(s[i])
for i in range(n):
res.append(s[i])
return ''.join(res)
方法三:字符串遍历拼接
若规定
Python
不能使用join()
函数,或规定Java
只能用String
,则使用此方法。
此方法与 方法二 思路一致,区别是使用字符串代替列表。
复杂度分析:
- 时间复杂度 O ( N ) O(N) O(N) : 线性遍历 s s s 并添加,使用线性时间;
- 空间复杂度
O
(
N
)
O(N)
O(N) : 假设循环过程中内存会被及时回收,内存中至少同时存在长度为
N
N
N 和
N
−
1
N-1
N−1 的两个字符串(新建长度为
N
N
N 的
resres
需要使用前一个长度 N − 1 N-1 N−1 的resres
),因此至少使用 O ( N ) O(N) O(N) 的额外空间。
代码
python
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
res = ""
for i in range(n, len(s)):
res += s[i]
for i in range(n):
res += s[i]
return res