A string such as "word"contains the following abbreviations:["word", "1ord", "W1rd", "wo1d", "Wor1", "2rd", "w2d", "WO2", "1o1d", "1or1", "W1r1", "1o2", "2r1", "3d", "W3", "4"]given a target string and a set of strings in a dictionary, find a abbreviation of Thistarget string with the smallest possible length such this it does not conflict with abbreviations of the strings in T He dictionary. each number or letter in the abbreviation is considered length= 1. For example, the abbreviation "A32BC" Have length = 4. Note:in the Caseof multiple answers as shown in the second example belowreturnAny one of them. Assume length of target string= m, and dictionary size = N. Assume that m≤21, n≤1000, and log2 (n) + m≤20. Examples:"Apple", ["Blade"], "A4" (because "5" or "4e" conflicts with "blade")"Apple", ["plain", "amber", "Blade"], "1p3" (Other valid answers include "AP3", "a3e", "2p2", "3le", "3L1").
Refer to Https://discuss.leetcode.com/topic/61799/java-bit-mask-dfs-with-pruning
Bit mask refer to http://bookshadow.com/weblog/2016/10/02/leetcode-minimum-unique-word-abbreviation/
1. The key idea of my solution are to preprocess the dictionary to transfer all the words to bit sequences (int):
比如apple 和 amper 字母相同设1,不同设0,所以得到10100
Another example is target= ' Apple ', word= ' amble ', Word's bitmask is 10011
In this process ignore and target length is different, get each dictionary inside the bitmask, the following address it as mask, so the bit in mask for 1 is the same as the target letter
A P p l EA m b L E1 0 0 1 1
2. Start to abbreviate the target word, but we do not directly abbreviated to decimal number, but first abbreviated to binary, 1 is reserved letters, 0 is replaced by numbers. The current abbreviation is curresult because Curresult is abbreviated by Target, so the 1 bit in Curresult is the same as the target letter.
For example, the abbreviation for the word manipulation m2ip6n can be converted to 100110000001
M a n i p u l a t i o nm 2 i p 6 N1 0 0 1 1 0 0 0 0 0 0 1
3. The bit in Mask 1 is the same as the target letter, while the bit in Curresult 1 is the same as the target letter, if
Curresult & mask = = Curresult,
That is Curresult 1 in the seat, mask also must be 1, then curresult also must be mask corresponding to the string of the abbreviation, so here conflict appear, so this curresult to be skip off
4. In all non-conflict curresult inside, find the shortest length, how to find the shortest length, you can maintain a current curresult length of a variable in recursion, and a variable to save the minimum length to update
5. Finally, the shortest length of the Curresult (which is currently just a binary abbreviation), reverts to the decimal abbreviation
This is the hardest bitmask I've ever done.
1 Public classSolution {2 Private intMinlen;3 Private intresult;4 5 Publicstring Minabbreviation (string target, string[] dictionary) {6 //Only keep words whose length = = Target in new dict, then compute their bit masks7Set<integer> Maskset =NewHashset<>();8 for(String s:dictionary) {9 if(target.length () = =s.length ()) {Ten Maskset.add (Getbitmask (S,target)); One } A } - - //DFS with pruning theMinlen = Target.length () +1; -result =-1; - -DFS (target,maskset,0,0,0); + - if(Minlen >target.length ()) { + return""; A } at - //convert result to Word - intzerocnt = 0; -String res = ""; - for(inti = Target.length ()-1; i>=0; i--) { - //encounter 0 to accumulate 0 consecutive numbers, encounter 1 fill the original char in intdigit = (Result & 1); - if(Digit = = 0){ to++zerocnt; +}Else { - if(zerocnt > 0){ theres = zerocnt +Res; *Zerocnt =0; $ }Panax Notoginsengres = Target.charat (i) +Res; - } theResult >>= 1; + } A if(zerocnt > 0) res = zerocnt +Res; the returnRes; + } - $ /** $ * - * @paramTarget - * @paramMaskset Masks of words in Dict the * @paramstart idx at Target - * @paramCurlen Current abbr ' s lengthWuyi */ the Private voidDFS (String target,set<integer> maskset,intStartintCurlen,intCurresult) { - //pruning, no need to continue, already not min length Wu if(Curlen >= Minlen)return; - About if(Start = =target.length ()) { $ //Check whether Curresult mask conflicts with words in Dict - for(intMask:maskset) { - /** - * The abbreviated m2ip6n of the word manipulation can be converted into 100110000001 A * m A n i p u l a t i o n + m 2 I p 6 n the 1 0 0 1 1 0 0 0 0 0 0 1 - * 0 for casual care, if this mask and the dict of a mask of all 1 coincident representatives of the location is exactly the same, $ * To explain the conflict between this mask and the dict word. the * We're looking for a mask that doesn't conflict the */ the if((Curresult & mask) = =Curresult) { the return;//Conflict - } in } the //No conflict happens, can use the if(Minlen >Curlen) { AboutMinlen =Curlen; theresult =Curresult; the } the return; + } - the //Case 1:replace chars from start in target with numberBayi for(inti = start; I < target.length (); i++) { the //the replaced char position is replaced by 0 so it is curresult<< (I+1-start), not replace it here regardless, we just go to I, after the decision by the backtrack inside the //Note: Word = w11d is not allowed to be replaced by numbers but with different meanings - if(Curlen = = 0 | | (Curresult &1) = = 1){ - //The latter is the last time the letter was reserved theDFS (target,maskset,i+1,curlen+1,curresult<< (i+1-start)); the } the } the - //Case 2:no Replace from Start (Curresult << 1) +1 represents the new this retains char, so it is added a theDFS (target,maskset,start+1,curlen+1, (curresult << 1) +1); the } the 94 //For example, Apple and amper the same letter set 1, different set 0, so get 10100 the Private intgetbitmask (String s1,string s2) { the intMask = 0; the for(inti = 0; I < s1.length (); i++) {98Mask <<= 1; About if(S1.charat (i) = =S2.charat (i)) { -Mask + = 1;101 }102 }103 returnMask;104 } the}
Leetcode:minimum Unique Word abbreviation