题目描述
给定字符串s和二维数组shift,其中,shift数组指示对字符串s进行的字符移动操作。
shift[i] = [direction, amount]
direction:0为向左移动,1为向右移动
amount:移动次数
示例:
Input: s = “abc”, shift = [[0,1],[1,2]]
Output: “cab”
Explanation:
[0,1] means shift to left by 1. “abc” -> “bca”
[1,2] means shift to right by 2. “bca” -> “cab”
解题思路
所谓移动,其实就是对字符串进行一个切割和拼接,核心操作就是substring
。但是使用substring
的时候想到一个问题,如果移动的次数比字符串本身的长度还要大呢?
写了几个例子之后发现,当移动长度达到字符串本身的长度时,其实字符串就回到了原样(相当于没有进行操作),因此,只需要对移动长度进行一个取余操作就可以。步骤大致如下:
(1)确定移动次数(即移动字符数x
)
(2)如果是向左移动,即将左边[0, x)
部分取下,拼接到字符串右边
(3)如果是向右移动,即将[length - x, end]
部分取下,拼接到字符串左边
(4)重复(1)(2)(3)直至所有的移动操作都完成
这个思路也是比较清晰,一步步照着写就可以,代码如下:
class Solution {
public String stringShift(String s, int[][] shift) {
if (s == null || s.length() == 0) {
return s;
}
for (int i = 0; i < shift.length; ++i) {
int dire = shift[i][0];
int amount = shift[i][1] % s.length();
String tmp = null;
if (dire == 0) {
tmp = s.substring(0, amount); // 注意,substring不改变原值
s = s.substring(amount);
s += tmp;
}
else {
tmp = s.substring(s.length() - amount);
s = s.substring(0, s.length() - amount);
s = tmp + s;
}
}
return s;
}
}
优化
题目给出了一个提示:
You may notice that left shift cancels the right shift, so count the total left shift times (may be negative if the final result is right shift), and perform it once.
左移和右移其实存在一个相互抵消的效果,因此可以对shift数组进行预处理,得到一个最终的移动方案(只有一个方向的移动)
时间复杂度上虽然和第一个方案一样,都是O(n)
,因为都要对shift
数组进行一次遍历,但是相比较第一个方案少了n-1
次字符串处理(其中n
是shift
数组的长度)。代码如下:
class Solution {
public String stringShift(String s, int[][] shift) {
if (s == null || s.length() == 0 || shift == null || shift.length == 0) {
return s;
}
// 对移动数组进行预处理
int[] finalShift = new int[2];
finalShift = shift[0];
for (int i = 1; i < shift.length; ++i) {
int dire = shift[i][0];
int amount = shift[i][1];
if (dire == finalShift[0]) {
finalShift[1] += amount;
}
else {
if (amount > finalShift[1]) {
finalShift[0] = (finalShift[0] == 0)? 1 : 0;
}
finalShift[1] = Math.abs(amount - finalShift[1]);
}
}
// 下面和方案1是一样的处理
String tmp = null;
int dire = finalShift[0];
int amount = finalShift[1] % s.length();
if (dire == 0) {
tmp = s.substring(0, amount);
s = s.substring(amount);
s += tmp;
}
else {
tmp = s.substring(s.length() - amount);
s = s.substring(0, s.length() - amount);
s = tmp + s;
}
return s;
}
}