Input: s ="84532", t ="34852"Output: trueExplanation: You can transform s into t using the following sort operations:"84 _53_ 2"(from index 2 to 3)->"84 _35_ 2""_843_ 52"(from index 0 to 2)->"_348_ 52"
Input: s ="34521", t ="23415"Output: trueExplanation: You can transform s into t using the following sort operations:"_3452_ 1"->"_2345_ 1""234 _51_ "->"234 _15_ "
We want to transform s into t by repeatedly sorting substrings. The only way to move a digit left is to sort a substring that includes it and all smaller digits to its left. So, for each digit in t, we must ensure that all smaller digits in s do not block it from moving to its position.
For each digit in t, we find its next occurrence in s (using queues for each digit). If any smaller digit appears before it in s, it cannot be moved left past that digit, so the transformation is impossible. This greedy approach works because sorting can only move a digit left if all smaller digits are already to its right.
classSolution {
public:bool isTransformable(string s, string t) {
vector<queue<int>> pos(10);
for (int i =0; i < s.size(); ++i) pos[s[i] -'0'].push(i);
for (char c : t) {
int d = c -'0';
if (pos[d].empty()) return false;
int idx = pos[d].front(); pos[d].pop();
for (int k =0; k < d; ++k) {
if (!pos[k].empty() && pos[k].front() < idx) return false;
}
}
return true;
}
};
classSolution {
publicbooleanisTransformable(String s, String t) {
Queue<Integer>[] pos =new Queue[10];
for (int i = 0; i < 10; i++) pos[i]=new LinkedList<>();
for (int i = 0; i < s.length(); i++) pos[s.charAt(i) -'0'].add(i);
for (char c : t.toCharArray()) {
int d = c -'0';
if (pos[d].isEmpty()) returnfalse;
int idx = pos[d].poll();
for (int k = 0; k < d; k++) {
if (!pos[k].isEmpty() && pos[k].peek() < idx) returnfalse;
}
}
returntrue;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution {
funisTransformable(s: String, t: String): Boolean {
val pos = Array(10) { ArrayDeque<Int>() }
for (i in s.indices) pos[s[i] - '0'].add(i)
for (c in t) {
val d = c - '0'if (pos[d].isEmpty()) returnfalseval idx = pos[d].removeFirst()
for (k in0 until d) {
if (pos[k].isNotEmpty() && pos[k].first() < idx) returnfalse }
}
returntrue }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution:
defis_transformable(self, s: str, t: str) -> bool:
from collections import deque
pos = [deque() for _ in range(10)]
for i, c in enumerate(s):
pos[int(c)].append(i)
for c in t:
d = int(c)
ifnot pos[d]:
returnFalse idx = pos[d].popleft()
for k in range(d):
if pos[k] and pos[k][0] < idx:
returnFalsereturnTrue
impl Solution {
pubfnis_transformable(s: String, t: String) -> bool {
use std::collections::VecDeque;
letmut pos =vec![VecDeque::new(); 10];
for (i, c) in s.chars().enumerate() {
pos[c asusize-'0'asusize].push_back(i);
}
for c in t.chars() {
let d = c asusize-'0'asusize;
if pos[d].is_empty() {
returnfalse;
}
let idx = pos[d].pop_front().unwrap();
for k in0..d {
if!pos[k].is_empty() &&*pos[k].front().unwrap() < idx {
returnfalse;
}
}
}
true }
}