首页 > 基础资料 博客日记
剑指offer-43、左旋转字符串
2025-11-27 09:30:02基础资料围观19次
这篇文章介绍了剑指offer-43、左旋转字符串,分享给大家做个参考,收藏Java资料网收获更多编程知识
题⽬描述
汇编语⾔中有⼀种移位指令叫做循环左移( ROL ),现在有个简单的任务,就是⽤字符串模拟这个指令的运算结果。对于⼀个给定的字符序列 S ,请你把其循环左移 K 位后的序列输出。例如,字符序列S=”abcXYZdef” ,要求输出循环左移3位后的结果,即“ XYZdefabc ”。是不是很简单?OK,搞定它!
思路及解答
这道题⽬的意思就是将前⾯ n 位,移动到后⾯,那么我们可以直接从第 n+1 位开始,遍历到最后⼀个,再拼接上前⾯ n 个。
暴力移位
通过k次单步左移实现循环左移。将第一个字符保存,其余字符前移,最后字符放到末尾
public class Solution {
public String leftRotateString(String str, int n) {
if (str == null || str.length() == 0 || n <= 0) {
return str;
}
char[] chars = str.toCharArray();
int len = chars.length;
n %= len; // 处理n大于字符串长度的情况
// 执行n次单步左移
for (int k = 0; k < n; k++) {
// 单步左移:保存首字符,其余前移,最后放回首字符
char firstChar = chars[0];
for (int i = 0; i < len - 1; i++) {
chars[i] = chars[i + 1];
}
chars[len - 1] = firstChar;
}
return new String(chars);
}
}
- 时间复杂度:O(k×n),其中k为移动次数,n为字符串长度
- 空间复杂度:O(1),只使用固定额外空间
字符串切片法(推荐)
值得注意的是, n 可能⼤于 str 的⻓度,那么这种情况下我们应该先对 str 的⻓度取余,保持严谨。即是: n = n % str.length(); 。
public class Solution {
public String LeftRotateString(String str, int n) {
if (str == null || str.length() == 0 || n <= 0) {
return str;
}
String ret = "";
n = n % str.length();
for (int i = n; i < str.length(); ++i) {
ret += str.charAt(i);
}
for (int i = 0; i < n; ++i) {
ret += str.charAt(i);
}
return ret;
}
}
- 时间复杂度 O(n)
- 空间复杂度 O(n) 。
或者可以用substring 的API
public class Solution {
public String leftRotateString(String str, int n) {
if (str == null || str.length() == 0 || n <= 0) {
return str;
}
int len = str.length();
n %= len; // 处理n大于字符串长度的情况
// 直接截取并拼接:后部分 + 前部分
return str.substring(n) + str.substring(0, n);
}
}
- 时间复杂度:O(n),substring操作需要线性时间
- 空间复杂度:O(n),创建新的字符串对象
三次反转(数学优美)
利用数学规律:BA = (A'B')',通过三次反转实现循环左移。
分别反转前n位、剩余部分,最后整体反转
public class Solution {
public String leftRotateString(String str, int n) {
if (str == null || str.length() == 0 || n <= 0) {
return str;
}
char[] chars = str.toCharArray();
int len = chars.length;
n %= len;
if (n == 0) return str; // 移动0位直接返回
// 第一步:反转前n个字符
reverse(chars, 0, n - 1);
// 第二步:反转剩余字符
reverse(chars, n, len - 1);
// 第三步:整体反转
reverse(chars, 0, len - 1);
return new String(chars);
}
/**
* 反转字符数组中指定范围的字符
* @param chars 字符数组
* @param start 起始索引
* @param end 结束索引
*/
private void reverse(char[] chars, int start, int end) {
while (start < end) {
// 交换首尾字符
char temp = chars[start];
chars[start] = chars[end];
chars[end] = temp;
start++;
end--;
}
}
}
- 时间复杂度:O(n),每个字符被访问两次
- 空间复杂度:O(1),原地操作,只使用常数空间
文章来源:https://www.cnblogs.com/sevencoding/p/19257019
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:

