class Solution:
def stringShift(self, s: str, shift: List[List[int]]) -> str:
total = 0
for direction, amount in shift:
if direction == 0:
total -= amount
else:
total += amount
total = total % len(s)
return s[-total:] + s[:-total] if total else s
class Solution {
public:
string stringShift(string s, vector<vector<int>>& shift) {
int total = 0;
int n = s.size();
for (auto &op : shift) {
if (op[0] == 0)
total -= op[1];
else
total += op[1];
}
total = ((total % n) + n) % n;
return s.substr(n - total) + s.substr(0, n - total);
}
};
class Solution {
public String stringShift(String s, int[][] shift) {
int total = 0;
int n = s.length();
for (int[] op : shift) {
if (op[0] == 0)
total -= op[1];
else
total += op[1];
}
total = ((total % n) + n) % n;
return s.substring(n - total) + s.substring(0, n - total);
}
}
var stringShift = function(s, shift) {
let total = 0;
let n = s.length;
for (let [direction, amount] of shift) {
if (direction === 0) {
total -= amount;
} else {
total += amount;
}
}
total = ((total % n) + n) % n;
return s.slice(n - total) + s.slice(0, n - total);
};
You are given a string s
and a list of shift operations shift
, where each operation is represented as a pair [direction, amount]
. The direction
can be:
0
for a left shift (move characters from the start to the end)1
for a right shift (move characters from the end to the start)amount
positions in the specified direction. Apply all shift operations in order and return the final string.
Constraints:
s.length
≤ 100shift.length
is between 1 and 100amount
is between 0 and 100At first glance, the problem suggests simulating each shift operation one by one. For every operation, we could slice the string and concatenate the parts according to the direction and amount. However, performing this for every operation could be inefficient, especially if there are many shifts.
On closer inspection, we realize that consecutive shifts can be combined: a left shift followed by a right shift is equivalent to a single net shift. Thus, instead of applying each shift in sequence, we can calculate the total net shift and apply it just once.
This optimization is crucial for both performance and code simplicity. It's like tracking how far you've moved left or right in total, rather than retracing every individual step.
k
, move the last k
characters to the front.len(s) - k
.This approach reduces the problem to a single string operation, regardless of the number of shift commands.
Let's use the example: s = "abcdefg"
, shift = [[1,1],[1,1],[0,2],[1,3]]
.
But instead of applying each, we calculate the net shift:
The optimized approach is much faster, especially when the number of operations is large.
By recognizing that multiple shift operations can be combined into a single net shift, we dramatically simplify the problem. This insight leads to a concise and efficient solution: just sum the left and right shifts, normalize the result, and perform one final string operation. The elegance comes from reducing repeated work and leveraging properties of modular arithmetic.