# 05.12.2024 [2337. Move Pieces to Obtain a String]
Move `L` left and `R` right to match strings #medium
05.12.2024
2337. Move Pieces to Obtain a String medium blog post substack youtube deep-dive
Join me on Telegram
Problem TLDR
Move
L
left andR
right to match strings #medium
Intuition
Let's move both pointers together and calculate the balance of
L
,R
and_
:
// R_R___L __RRL__ R b L
// j // jk
// j . i . +1-1=1
// j . i . +1-1=1
// j . i . -1=0 +1=2
// j. i. +1=3 -1 (check R==0)
// j i +1-1=3
// j i -1=2 +1=0
Some observations:
the final balance should be
0
we should eliminate the impossible scenarios (that's where the hardness of this task begins)
to simplify the corner cases let's split this into pass forward and pass backwards (then we have ugly long solution but its werks)
Now, the more clever way of solving ignore the spaces
_
and only check the balance ofl
andr
be not negative. The corner case would beLR
->RL
and for this check we don't havel > 0
andr > 0
together.Another, much simpler way of thinking: move separate pointers instead of a single, and skip the spaces
_
, then compare:
s[i] == t[j]
letters should matchsome indexes rules: from
start
R
goes forwardi <= j
,L
goes backwardi >= j
Approach
slow down and think one step at a time
the good idea of separate pointers eliminates all corner cases (so think broader in a space of ideas before thinking in a space of implementations)
Complexity
Time complexity: $$O(n)$$
Space complexity: $$O(1)$$
Code
fun canChange(start: String, target: String): Boolean {
var l = 0; var r = 0
for ((i, s) in start.withIndex()) {
val t = target[i]
if (s == 'R') r++
if (t == 'L') l++
if (l * r > 0) return false
kk
if (s == 'L' && --l < 0) return false
k
return l == 0 && r == 0
}
pub fn can_change(start: String, target: String) -> bool {
let (mut i, mut j, s, t, n) =
(0, 0, start.as_bytes(), target.as_bytes(), start.len());
while i < n || j < n {
while i < n && s[i] == b'_' { i += 1 }
while j < n && t[j] == b'_' { j += 1 }
if i == n || j == n || s[i] != t[j] ||
s[i] == b'L' && i < j || s[i] == b'R' && i > j { break }
i += 1; j += 1
}; i == n && j == n
}
bool canChange(string s, string t) {
int l = 0, r = 0;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == 'R') r++;
if (t[i] == 'L') l++;
if (l * r > 0) return 0;
if (t[i] == 'R' && --r < 0) return 0;
if (s[i] == 'L' && --l < 0) return 0;
}
return l == 0 && r == 0;
}