11package g3401_3500 .s3435_frequencies_of_shortest_supersequences ;
22
3- // #Hard #2025_01_26_Time_728_(100.00%)_Space_50.28_(100.00%)
3+ // #Hard #Array #String #Bit_Manipulation #Graph #Enumeration #Topological_Sort
4+ // #2025_01_27_Time_751_(100.00%)_Space_49.95_(100.00%)
45
56import java .util .ArrayList ;
67import java .util .Arrays ;
1011import java .util .Map ;
1112
1213public class Solution {
13- private Map <String , Boolean > buildWordMap (List <String > words ) {
14- Map <String , Boolean > mp = new HashMap <>();
15- for (String x : words ) {
16- mp .put (x , true );
14+ public List <List <Integer >> supersequences (String [] wordsArray ) {
15+ List <String > words = new ArrayList <>(Arrays .asList (wordsArray ));
16+ Collections .sort (words );
17+ int [] bg = new int [26 ];
18+ int [] ed = new int [26 ];
19+ Arrays .fill (bg , -1 );
20+ Arrays .fill (ed , 0 );
21+ int [] tans = initializeArrays (words );
22+ List <String > wtc = buildWtcList (words , tans );
23+ updateBgEdArrays (wtc , bg , ed );
24+ List <List <Integer >> ans = new ArrayList <>();
25+ if (wtc .isEmpty ()) {
26+ ans .add (convertArrayToList (tans ));
27+ } else {
28+ processNonEmptyWtc (wtc , tans , bg , ed , ans );
1729 }
18- return mp ;
30+ return ans ;
1931 }
2032
21- private Map <Character , Boolean > buildCharMap (List <String > words ) {
33+ private int [] initializeArrays (List <String > words ) {
34+ Map <String , Boolean > mp = new HashMap <>();
2235 Map <Character , Boolean > mp2 = new HashMap <>();
23- for (String x : words ) {
24- mp2 .put (x .charAt (0 ), true );
25- mp2 .put (x .charAt (1 ), true );
36+ for (String word : words ) {
37+ mp .put (word , true );
38+ mp2 .put (word .charAt (0 ), true );
39+ mp2 .put (word .charAt (1 ), true );
2640 }
27- return mp2 ;
28- }
29-
30- private int [] initializeAnswerArray (Map <String , Boolean > mp , Map <Character , Boolean > mp2 ) {
3141 int [] tans = new int [26 ];
32- Arrays .fill (tans , 0 );
3342 for (char c = 'a' ; c <= 'z' ; c ++) {
3443 String aux = "" + c + c ;
3544 if (mp .containsKey (aux )) {
@@ -41,132 +50,138 @@ private int[] initializeAnswerArray(Map<String, Boolean> mp, Map<Character, Bool
4150 return tans ;
4251 }
4352
44- private List <String > filterWords (List <String > words , int [] tans ) {
53+ private List <String > buildWtcList (List <String > words , int [] tans ) {
4554 List <String > wtc = new ArrayList <>();
46- for (String x : words ) {
47- if (tans [x .charAt (0 ) - 'a' ] != 2 && tans [x .charAt (1 ) - 'a' ] != 2 ) {
48- wtc .add (x );
55+ for (String word : words ) {
56+ if (tans [word .charAt (0 ) - 'a' ] != 2 && tans [word .charAt (1 ) - 'a' ] != 2 ) {
57+ wtc .add (word );
4958 }
5059 }
5160 return wtc ;
5261 }
5362
54- private void updateBoundaries (List <String > wtc , int [] bg , int [] ed ) {
55- for (int i = 0 ; i < wtc .size (); i ++) {
56- int l = wtc .get (i ).charAt (0 ) - 'a' ;
57- if (bg [l ] == -1 ) {
58- bg [l ] = i ;
59- }
60- ed [l ] = i ;
63+ private void updateBgEdArrays (List <String > wtc , int [] bg , int [] ed ) {
64+ for (String word : wtc ) {
65+ int l = word .charAt (0 ) - 'a' ;
66+ if (bg [l ] == -1 ) bg [l ] = wtc .indexOf (word );
67+ ed [l ] = wtc .indexOf (word );
6168 }
6269 }
6370
64- private List <Integer > findMinimalSolutions (List <String > wtc , int [] tans , int [] bg , int [] ed ) {
71+ private void processNonEmptyWtc (
72+ List <String > wtc , int [] tans , int [] bg , int [] ed , List <List <Integer >> ans ) {
73+ List <Integer > ns = buildNsList (tans );
74+ List <Integer > gm = buildGmList (wtc , tans , bg , ed , ns );
75+ int minb = findMinBits (gm );
76+ addMinimalAnswers (gm , minb , ns , tans , ans );
77+ }
78+
79+ private List <Integer > buildNsList (int [] tans ) {
6580 List <Integer > ns = new ArrayList <>();
6681 for (int i = 0 ; i < 26 ; i ++) {
6782 if (tans [i ] == 1 ) {
6883 ns .add (i );
6984 }
7085 }
86+ return ns ;
87+ }
88+
89+ private List <Integer > buildGmList (
90+ List <String > wtc , int [] tans , int [] bg , int [] ed , List <Integer > ns ) {
7191 List <Integer > gm = new ArrayList <>();
7292 for (int i = 0 ; i < (1 << ns .size ()); i ++) {
73- if (isValidSolution (i , ns , wtc , tans . clone () , bg , ed )) {
93+ if (isValidConfiguration (i , wtc , tans , bg , ed , ns )) {
7494 gm .add (i );
7595 }
7696 }
7797 return gm ;
7898 }
7999
80- private boolean isValidSolution (
81- int i , List <Integer > ns , List < String > wtc , int [] tans , int [] bg , int [] ed ) {
100+ private boolean isValidConfiguration (
101+ int i , List <String > wtc , int [] tans , int [] bg , int [] ed , List < Integer > ns ) {
82102 int [] indg = new int [26 ];
83- Arrays .fill (indg , 0 );
103+ updateTansForConfiguration (i , tans , ns );
104+ for (String word : wtc ) {
105+ if (tans [word .charAt (0 ) - 'a' ] != 2 && tans [word .charAt (1 ) - 'a' ] != 2 ) {
106+ indg [word .charAt (1 ) - 'a' ]++;
107+ }
108+ }
109+ List <Integer > chk = buildChkList (indg , tans );
110+ processChkList (chk , wtc , tans , bg , ed , indg );
111+ return Arrays .stream (indg ).max ().orElse (0 ) == 0 ;
112+ }
113+
114+ private void updateTansForConfiguration (int i , int [] tans , List <Integer > ns ) {
84115 for (int j = 0 ; j < ns .size (); j ++) {
85116 if ((i & (1 << j )) != 0 ) {
86117 tans [ns .get (j )] = 2 ;
87118 } else {
88119 tans [ns .get (j )] = 1 ;
89120 }
90121 }
91- for (String w : wtc ) {
92- if (tans [w .charAt (0 ) - 'a' ] != 2 && tans [w .charAt (1 ) - 'a' ] != 2 ) {
93- indg [w .charAt (1 ) - 'a' ]++;
94- }
95- }
96- return processIndegrees (indg , tans , wtc , bg , ed );
97122 }
98123
99- private boolean processIndegrees ( int [] indg , int [] tans , List <String > wtc , int [] bg , int [] ed ) {
124+ private List <Integer > buildChkList ( int [] indg , int [] tans ) {
100125 List <Integer > chk = new ArrayList <>();
101126 for (int j = 0 ; j < 26 ; j ++) {
102127 if (indg [j ] == 0 && tans [j ] == 1 ) {
103128 chk .add (j );
104129 }
105130 }
131+ return chk ;
132+ }
133+
134+ private void processChkList (
135+ List <Integer > chk , List <String > wtc , int [] tans , int [] bg , int [] ed , int [] indg ) {
106136 while (!chk .isEmpty ()) {
107137 int u = chk .remove (chk .size () - 1 );
108- if (bg [u ] == -1 ) {
109- continue ;
110- }
138+ if (bg [u ] == -1 ) continue ;
139+
111140 for (int j = bg [u ]; j <= ed [u ]; j ++) {
112141 int l = wtc .get (j ).charAt (1 ) - 'a' ;
113- if (tans [l ] == 2 ) {
114- continue ;
115- }
142+ if (tans [l ] == 2 ) continue ;
116143 indg [l ]--;
117144 if (indg [l ] == 0 ) {
118145 chk .add (l );
119146 }
120147 }
121148 }
122- return Arrays .stream (indg ).max ().getAsInt () == 0 ;
123149 }
124150
125- public List <List <Integer >> supersequences (String [] wordsArray ) {
126- List <String > words = new ArrayList <>(Arrays .asList (wordsArray ));
127- Collections .sort (words );
128- int [] bg = new int [26 ];
129- Arrays .fill (bg , -1 );
130- int [] ed = new int [26 ];
131- Arrays .fill (ed , 0 );
132- Map <String , Boolean > mp = buildWordMap (words );
133- Map <Character , Boolean > mp2 = buildCharMap (words );
134- int [] tans = initializeAnswerArray (mp , mp2 );
135- List <String > wtc = filterWords (words , tans );
136- updateBoundaries (wtc , bg , ed );
137- List <List <Integer >> ans = new ArrayList <>();
138- if (wtc .isEmpty ()) {
139- List <Integer > tansList = new ArrayList <>();
140- for (int t : tans ) {
141- tansList .add (t );
142- }
143- ans .add (tansList );
144- return ans ;
151+ private int findMinBits (List <Integer > gm ) {
152+ int minb = 20 ;
153+ for (int x : gm ) {
154+ minb = Math .min (minb , countSetBits (x ));
145155 }
146- List <Integer > gm = findMinimalSolutions (wtc , tans , bg , ed );
147- int minb = gm .stream ().mapToInt (Integer ::bitCount ).min ().getAsInt ();
148- List <Integer > ns = new ArrayList <>();
149- for (int i = 0 ; i < 26 ; i ++) {
150- if (tans [i ] == 1 ) {
151- ns .add (i );
156+ return minb ;
157+ }
158+
159+ private void addMinimalAnswers (
160+ List <Integer > gm , int minb , List <Integer > ns , int [] tans , List <List <Integer >> ans ) {
161+ for (int x : gm ) {
162+ if (countSetBits (x ) == minb ) {
163+ updateTansForConfiguration (x , tans , ns );
164+ ans .add (convertArrayToList (tans ));
152165 }
153166 }
154- for (int x : gm ) {
155- if (Integer .bitCount (x ) == minb ) {
156- for (int j = 0 ; j < ns .size (); j ++) {
157- if ((x & (1 << j )) != 0 ) {
158- tans [ns .get (j )] = 2 ;
159- } else {
160- tans [ns .get (j )] = 1 ;
161- }
162- }
163- List <Integer > tansList = new ArrayList <>();
164- for (int t : tans ) {
165- tansList .add (t );
166- }
167- ans .add (tansList );
167+ }
168+
169+ private int countSetBits (int x ) {
170+ int count = 0 ;
171+ while (x > 0 ) {
172+ if ((x & 1 ) != 0 ) {
173+ count ++;
168174 }
175+ x >>= 1 ;
169176 }
170- return ans ;
177+ return count ;
178+ }
179+
180+ private List <Integer > convertArrayToList (int [] array ) {
181+ List <Integer > list = new ArrayList <>();
182+ for (int num : array ) {
183+ list .add (num );
184+ }
185+ return list ;
171186 }
172187}
0 commit comments