描述
给定一个字符串和一个偏移量,根据偏移量偏移字符串(从左向右偏移)
样例
对于字符串 "abcdefg"
.
offset=0 => "abcdefg"
offset=1 => "gabcdef"
offset=2 => "fgabcde"
offset=3 => "efgabcd"
挑战
在数组上原地旋转,使用O(1)的额外空间
解题思路
首先从在一个宏观的角度来看,偏移会把后几个字符移动到整个字符串的开头,比如"offset=1 => "gabcdef" 会把 g 移动到字符串的开头,"offset=3 => "efgabcd"会把 efg 移动到字符串的开头。这样来看,有点类似于反转数组。所以我们先反转整个字符串。
// 原字符串
str = "abcdefg"
// 反转后
str = "gfedcba"
但是在反转后,字符的顺序出现了变化,变成了局部逆序的数组了,因此我们需要对原先的后几个字符和前几个字符分别再做一个逆序。
// 假设offset = 3, 原字符
str = "abcdefg"
// 反转后
str = "gfedcba"
// 对前3个字符再做一个逆序
str = "efgdcba"
// 对后4个字符再做一次逆序
str + "efgabcd"
源码
public class Solution
{
public static void rotateString(char[] str, int offset)
{
if(str == null || str.length == 0 || offset % str.length == 0)
return;
// 这里考虑到offset 大于 str.length的情况
// 例如str.length = 7 offset = 9
// 实际上每个字符实际偏移的长度是2
offset = offset % str.length;
reverse(str, 0, str.length-1); // 先对整个字符串做反转
reverse(str, 0, offset-1); // 对前几个字符做局部反转
reverse(str, offset, str.length-1); // 对后几个字符做局部反转
}
public static void reverse(char[] str, int start, int end)
{
for(int i = start, j = end; i < j; i++, j--)
{
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
}