Remove Duplicate Letters

本文介绍了一种算法,用于从仅包含小写字母的字符串中移除重复字母,并确保结果按字典序最小。通过示例解释了算法逻辑,并提供了一个Java实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值