-
Notifications
You must be signed in to change notification settings - Fork 110
/
solution.java
68 lines (65 loc) · 2.06 KB
/
solution.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;
import java.io.*;
import java.util.*;
public class Solution {
static public class CharData {
int total;
int skipped;
int taken;
boolean hasToTake(){
return 2*skipped == total;
}
boolean hasToSkip(){
return 2*taken == total;
}
void putBack(){
taken--;
skipped++;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = new StringBuilder(in.nextLine()).reverse().toString();
CharData cd[] = new CharData['z' - 'a' + 1];
for(int i=0;i<cd.length;i++){
cd[i]=new CharData();
}
for (int i = 0; i < s.length(); i++) {
cd[s.charAt(i)-'a'].total++;
}
// Character counts we need in the shuffled
// version of our original string
char [] r = new char[s.length()/2];
int ri=0;
/* See if this character should appear before any
previous ones. Basically, if this char is smaller
than the previous char, and the previous char
still occurs in the chars of the shuffled string,
we can the safely replace the previous char
with this one. That's so because we should be
able to still create a valid string which contains
both characters although the order will differs.
*/
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
CharData di = cd[ch-'a'];
if(di.hasToSkip()){
di.skipped++;
}else {
while(ri>0 && r[ri-1]>ch && !cd[r[ri-1]-'a'].hasToTake()){
cd[r[--ri]-'a'].putBack();
}
r[ri++]=ch;
di.taken++;
}
}
System.out.println(new String(r)); // // return string which is the lexicographically smallest valid string r
in.close();
}
}