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”
参考了 http://www.bubuko.com/infodetail-1249912.html 的做法
不过有一点要说明一下, 例如 Given “cbacdcbc”
a: 2
b: 1 , 6
c: 0 , 3 , 5 ,7
d: 4
每一个字符只要跟自己后面的字符比较就可以了,也就是每一个字符看可不可以放在它后面的字符的前面。
理由如下 : 假设有 v ,x ,y ,z 这么五个字符,假设v不可以放在x,y,z的前面,下面该判断x是否可以放在y,z的前面,如果x可以放在y,z的前面,但x不可以放在v的前面, 说明v是可以放在x的前面的,而y,z是可以放在x的后面的,也就是v也可以放在y,z的后面,综上说明v是可以放在x,y,z的后面,与前面的v不可以放在x,y,z的前面矛盾, 那么也就是说明了x如果是可以放在y,z 的前面,那么x也就是可以放在当前剩下的所有字符的前面,也就是每一个字符只要跟自己后面的字符去比较,判断是不是都可以放在剩下字符的前面就可以了。
public class Solution {
public String removeDuplicateLetters(String s) {
int n=s.length();
if(n==0) return "";
StringBuilder res =new StringBuilder();
Map<Character,ArrayList<Integer>> chIdxMap=new HashMap<Character,ArrayList<Integer>>();
List<Character> sortLs=new ArrayList<Character>();
for(int i=0;i<n;i++)
{
char ch=s.charAt(i);
if(chIdxMap.containsKey(ch))
{
chIdxMap.get(ch).add(i);
}else {
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(i);
chIdxMap.put(ch,temp);
sortLs.add(ch);
}
}
Collections.sort(sortLs);
while(sortLs.size()!=0)
{ int firstIdx=0;
for(int i=0;i<sortLs.size();i++)
{
char ch=sortLs.get(i);
firstIdx=chIdxMap.get(ch).get(0);
int j=i+1;
for(;j<sortLs.size();j++)
{
ArrayList<Integer> temp = chIdxMap.get(sortLs.get(j));
if(firstIdx> temp.get(temp.size()-1))
break;
}
if(j==sortLs.size())
{
res.append(ch);
sortLs.remove(i);
break;
}
}
for(int i=0;i<sortLs.size();i++)
{
ArrayList<Integer> tempTwo=chIdxMap.get(sortLs.get(i));
while(tempTwo.size()!=0 && tempTwo.get(0) < firstIdx )
{
tempTwo.remove(0);
}
}
}
return res.toString();
}
}