左旋转字符串

力扣题目链接

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

示例 1:
输入: s = “abcdefg”, k = 2
输出: “cdefgab”

示例 2:
输入: s = “lrloseumgh”, k = 6
输出: “umghlrlose”

限制:
1 <= k < s.length <= 10000

思路

为了让本题更有意义,提升一下本题难度:不能申请额外空间,只能在本串上操作

不能使用额外空间的话,模拟在本串操作要实现左旋转字符串的功能还是有点困难的。

那么我们可以想一下上一题目字符串:花式反转还不够!中讲过,使用整体反转+局部反转就可以实现,反转单词顺序的目的。

这道题目也非常类似,依然可以通过局部反转+整体反转 达到左旋转的目的。

具体步骤为:

  1. 反转区间为前n的子串
  2. 反转区间为n到末尾的子串
  3. 反转整个字符串

最后就可以得到左旋n的目的,而不用定义新的字符串,完全在本串上操作。

例如 :示例1中 输入:字符串abcdefg,n=2

如图:

左旋转字符串 - 图1

最终得到左旋2个单元的字符串:cdefgab

思路明确之后,那么代码实现就很简单了

代码如下:

  1. class Solution {
  2. /*
  3. * 双指针
  4. *
  5. * @param s
  6. * @param n
  7. * @return
  8. */
  9. public String reverseLeftWords(String s, int n) {
  10. // 先将字符串局部反转
  11. s = reverse(s, 0, n - 1);
  12. s = reverse(s, n, s.length() - 1);
  13. // 再将字符串进行全局反转
  14. s = reverse(s, 0, s.length() - 1);
  15. return s;
  16. }
  17. /**
  18. * 反转区间内的字符串
  19. *
  20. * @param s
  21. * @param i
  22. * @param j
  23. * @return
  24. */
  25. public String reverse(String s, int i, int j) {
  26. char[] chars = s.toCharArray();
  27. for (; i < j; i++, j--) {
  28. char temp = chars[i];
  29. chars[i] = chars[j];
  30. chars[j] = temp;
  31. }
  32. return String.valueOf(chars);
  33. }
  34. }

是不是发现这代码也太简单了,哈哈。

总结

此时我们已经反转好多次字符串了,来一起回顾一下吧。

在这篇文章344.反转字符串,第一次讲到反转一个字符串应该怎么做,使用了双指针法。

然后发现541. 反转字符串II,这里开始给反转加上了一些条件,当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。

后来在151.翻转字符串里的单词中,要对一句话里的单词顺序进行反转,发现先整体反转再局部反转 是一个很妙的思路。

最后再讲到本题,本题则是先局部反转再 整体反转,与151.翻转字符串里的单词类似,但是也是一种新的思路。