持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串 "abcdefg" 和数字 2,该函数将返回左旋转两位得到的结果 "cdefgab"。
示例 1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:
输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
限制:
1 <= k < s.length <= 10000
解题思路
我一开始看到这道题,想的是创建一个StringBuffer用来实现这道题,具体思路是
- 创建一个
StringBuffer - 将原字符串
k个字符后面的全部添加到StringBuffer里 - 将要反转的
k个字符找出来,进行反转,再添加到StringBuffer这样就实现了题目要求的旋转,虽然这种方法也可以解决本题,但是这样做的话就需要使用辅助空间
如果本题提升下难度,再加上一个条件:不可以申请额外空间,只能在本串上操作
那么上面的解题思路就不适用了,但是在上一道题颠倒字符串中的单词中,我们使用了全部反转+局部反转思路解决了那题
本题类似,同样可以使用那个思路,具体步骤为
- 反转字符串中要移动到后面的子串
- 反转还没有进行反转的字符串
- 反转整个字符串
这么一通操作下来,即不需要额外空间,还在本串上完成了反转
为了方便大家理解,我们举个例子并画图来说明,当字符串 s = abcdefg, k = 2
最终得到的字符串为CDEFGAB,就是我们要的答案
代码:(JAVA实现)
public String reverseLeftWords(String s, int n) {
StringBuilder res = new StringBuilder(s);
//反转区间到前n的子串
reverString(res,0,n-1);
//反转区间n到末尾的子串
reverString(res,n,res.length()-1);
//反转整个字符串
reverString(res,0,res.length()-1);
return res.toString();
}
//因为需要反转好几次,如果每次都要写反转逻辑,代码太啰嗦了,我直接将反转逻辑封装成了一个方法,需要的时候直接调用传参
public static void reverString(StringBuilder s,int start,int end) {
while (start < end) {
char temp = s.charAt(start);
s.setCharAt(start,s.charAt(end));
s.setCharAt(end,temp);
start++;
end--;
}
}
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)