Skip to content

Commit 97cd4ed

Browse files
committed
Solved "Reverse Shuffle Merge"
1 parent 8f64d93 commit 97cd4ed

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

reverseShuffleMerge.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//+ Jonas Raoni Soares Silva
2+
//@ http://raoni.org
3+
4+
function reverseShuffleMerge(s) {
5+
const required = new Map();
6+
const used = new Map();
7+
const available = new Map();
8+
for (const c of s) {
9+
// As the string "S" is formed by the reverse of S + scrambled S, it means each character should appear twice...
10+
// So we know which characters should be part of the original string and how many times they should appear
11+
const amount = (required.get(c) || 0) + .5;
12+
// Keep the required amount (static reference) of characters to form the string
13+
required.set(c, amount);
14+
// As we collect chars, this will be used to monitor how many still exists ahead...
15+
available.set(c, amount * 2);
16+
}
17+
const origin = [];
18+
// Reverse the string by making a loop from the end to the beginning
19+
for (let i = s.length; i--; ) {
20+
const c = s[i];
21+
const count = used.get(c) || 0;
22+
// If the current character is useful
23+
if (count < required.get(c)) {
24+
// Check if we can replace the last character we stored by a lexicographically smaller one...
25+
for (let last; origin.length && (last = origin[origin.length - 1]) > c; origin.pop()) {
26+
if (used.get(last) + available.get(last) <= required.get(last))
27+
break;
28+
used.set(last, used.get(last) - 1);
29+
}
30+
// Use character
31+
used.set(c, count + 1);
32+
origin.push(c);
33+
}
34+
// Decrease the availability
35+
available.set(c, available.get(c) - 1);
36+
}
37+
return origin.join('');
38+
}

0 commit comments

Comments
 (0)