LeetCode 剑指 Offer 58 - II. 左旋转字符串
题目描述

题意分析
将字符串开头的
n个字符整体移到末尾,前缀和剩余后缀各自的内部顺序不变,返回旋转后的字符串。
解法:字符串切分
核心思路
[!blue]
设字符串长度为
L,把原串写成A + B,其中A是要移走的前缀,B是剩下的后缀。移走A后,B自然排到最前,再把A接到末尾,结果就是B + A,不需要逐次移动字符。代码用
k = n % L表示有效偏移,因为左旋一整圈又回到原串;题目保证1 <= n < L,所以合法输入下k就是n。切分点为k,前缀取半开区间[0, k),后缀取[k, L),两段恰好覆盖原串且不重叠。
解题步骤
- 确定有效偏移
k = n % L,Java 中直接用变量n保存它。- 取从下标
k到末尾的后缀,再取前k个字符作为前缀。- 按后缀、前缀的顺序拼接并返回。
代码实现
class Solution {
public String reverseLeftWords(String s, int n) {
int len = s.length();
n %= len;
// 后缀放在前面,原来的前 n 个字符整体移到末尾。
return s.substring(n) + s.substring(0, n);
}
}
func reverseLeftWords(s string, n int) string {
if len(s) == 0 {
return s
}
k := n % len(s)
// 后缀放在前面,原来的前 n 个字符整体移到末尾。
return s[k:] + s[:k]
}
复杂度分析
- 时间复杂度:$O(L)$,其中
L为字符串长度;拼接结果需要复制L个字符单位。- 空间复杂度:$O(L)$,用于返回的新字符串;Java 截取子串还需 $O(L)$ 临时空间,Go 的两段切片为视图。
关键点总结
[!green]
- 切分点
k是未被移动部分的第一个下标,前缀长度正好为k。- 拼接后长度及每个字符的出现次数不变。
易错点总结
[!yellow]
- 把前缀再接后缀只会得到原串。
- 子串右端点不包含在内,前缀应截取到
k,不是k - 1。- 整体反转会改变段内顺序,不是左旋转。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 189. 轮转数组 | 中等 | 循环平移可用取模与分段反转,本题向左旋转字符,原题向右旋转数组,方向需对应。 |
| 796. 旋转字符串 | 简单 | 原题判断是否存在某次旋转可匹配,本题给定偏移量并返回实际旋转结果。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!