316. 去除重复字 mark

题目

截图自官方

代码

class Solution {
    // 没想出来
    // 贪心,解法2,空间复杂度,注意为O(1),时间复杂度O(n),因为while循环受字母表总数影响,是常数级的。
    // 思路:就是让结果首字母的字典序最小,其位置之后还必须有原s出现过的所有字符。
    // 先记录每个出现的字符出现的最后位置
    // 遍历字符串,如果当前字符字典序小于栈首的,且栈首字符的最后出现位置在当前字符之后,则从栈中弹出,将当前字符压入。
    // 这里需要注意的问题就是对后来出现的重复字符的处理如abcda,不出的话结果会是abcda
    // abcabcd

    // public String removeDuplicateLetters(String s) {
    //     Map<Character,Integer> last=new HashMap();
    //     // 记录每个字符最后出现的位置
    //     for(int i=0;i<s.length();i++){
    //         last.put(s.charAt(i),i);
    //     }
    //     Stack<Character> temp=new Stack();
    //     // 记录已添加的,防止添加重复的
    //     Set<Character> seen=new HashSet();
    //     for(int i=0;i<s.length();i++){
    //     if(!seen.contains(s.charAt(i))){
    //     while(!temp.empty()&&temp.peek()>s.charAt(i)&&i<last.get(temp.peek())){
    //             char t=temp.pop();
    //             // 注意这里
    //             seen.remove(t);
    //         }
    //         temp.push(s.charAt(i));
    //         seen.add(s.charAt(i));
    //     }

    //     }

    //     // 第一次看到对栈这样的操作。
    //     // 这样可以把栈中的元素从栈底为首的顺序取出来(像队列)
    //     StringBuilder res=new StringBuilder(temp.size());
    //     for(Character c:temp){
    //         res.append(c);
    //     }
    //     return res.toString();

    // }

//          解法一,递归解法。大思路是一样。时间:O(n),空间O()
    public String removeDuplicateLetters(String s) {
           int[] count=new int[26];
           for(int i=0;i<s.length();i++){
               count[s.charAt(i)-'a']++;
           }
           int min=0;
           for(int i=0;i<s.length();i++){
            //    寻找字典序最小的字符
               if(s.charAt(i)<s.charAt(min)){
                   min=i;
               }
            //    当前字符只有该位置有一个了,必须结束寻找,以min为首了。
               if(--count[s.charAt(i)-'a']==0){
                   break;
               }
           }
        //    注意api
           return s.length()==0?"":s.charAt(min)+removeDuplicateLetters(s.substring(min+1).replaceAll(s.charAt(min)+"",""));
    }
}

 

笔记

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值