316. Remove Duplicate Letters, duplicateletters
Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
Example:
Given"bcabc"
Return"abc"
Given"cbacdcbc"
Return"acdb"
Solution:
Abccdab
Step 1: Remove uppercase letters from abcdab
Step 2: store {d = 3, B = 5, c = 2, a = 4} in map}
Step 3: splicing output
Principle: The first element must appear between 0 and 2 (because the position of c in the string is 2 at the last time. If no element exists between 0 and 2, then the concatenated string will not contain the c character)
Between 0 and 2, the element marked as 2 must be greater than once, and the element marked as 2 is the largest of the currently spliced strings.
Based on this principle, the values of B and end are controlled and the smallest element in (B, end] is selected to splice strings.
1 public class Solution {2 public String removeDuplicateLetters (String s) {3 // letter deduplication 4 Character old = null; 5 Character newc; 6 StringBuilder stb = new StringBuilder (); 7 for (int I = 0; I <s. length (); I ++) {8 newc = s. charAt (I); 9 if (old! = Newc) {10 stb. append (newc); 11} 12 old = newc; 13} 14 s = stb. toString (); 15 16 // use the automatic overwrite of map to obtain the last occurrence of the letter badge key-Value Pair 17 Map <Character, Integer> map = new HashMap <Character, integer> (); 18 for (int I = 0; I <s. length (); I ++) {19 map. put (s. charAt (I), I); 20} 21 int len = map. size (); 22 23 // use StringBuilder to concatenate and output 24 StringBuilder sb = new StringBuilder (); 25 int B = 0; 26 int end = findMinValue (map ); 27 Character val = findKeyByValue (map, end); 28 while (sb. length () <len) {29 Character minc = 'Z' + 1; 30 for (int I = B; I <= end; I ++) {31 Character cm = s. charAt (I); 32 if (cm <minc & cm <= val & map. containsKey (cm) {33 minc = cm; 34 B = I + 1; 35} 36} 37 sb. append (minc + ""); 38 // Delete 39 maps from map. remove (minc); 40 if (minc = val) {41 end = findMinValue (map); 42 val = findKeyByValue (map, end ); 43} 44} 45 46 47 return sb. toString (); 48} 49 public Character findKeyByValue (Map <Character, Integer> map, int val) {50 for (Map. entry <Character, Integer> entry: map. entrySet () {51 if (entry. getValue () = val) {52 return entry. getKey (); 53} 54} 55 return null; 56} 57 public int findMinValue (Map <Character, Integer> map) {58 int minkey = Integer. MAX_VALUE; 59 for (Integer index: map. values () {60 if (index <minkey) {61 minkey = index; 62} 63} 64 return minkey; 65} 66}
The key to this question lies in the code of the first line: limit the range of letters to be output.