zoukankan      html  css  js  c++  java
  • [LeetCode No.316] 去除重复字母

    题目

    题解

    这道题,还真木有想出来
    看了一下官方视频解答,讲的比较好

    大致思路:
    例如:
    输入:s = "bcabc"
    输出:"abc"

    b->bc>bca(由于c比a字典序大,所以这次考虑可以把c弹出去,看到c在后面还会出现,所以可以弹出去)->ba->a(同理弹b)->ab->abc
    可以看到,弹出的时候满足后进先出,所以可以基本确定这里需要使用“栈”结构。

    确定使用栈后,可以这么来看,一开始b压入,c压入。当要压入a时,因为此时栈顶元素“c”比“a”字典序大。如若a能在c前面肯定总字典序要更小
    那么这时候看“a”后面还有没有“c”,显然有,那么可以把“c”pop出去,再把“a”压入。
    Tip:显然如果后续在字符串遇见已经在栈内的字符。我们可以直接跳过。 (因为如果他在栈顶。没必要。如果在栈内,栈内的“它”肯定前小后大,所以忽略)
    https://leetcode-cn.com/problems/remove-duplicate-letters/solution/zhan-by-liweiwei1419/) 这个题解后四段更为详细

    代码

    public class Solution {
        public String removeDuplicateLetters(String s) {
            int [] visited = new int[26];              //已经存在于栈中 标志数组
            int [] lastIndex = new int[26];              //存在字符,最后一次在字符串出现的index
    
            for (int i = 0; i < s.length(); i++) {
            lastIndex[s.charAt(i)-'a'] = i;                  //记录所有存在字符,最后一次出现的index
            }
    
            Deque<Character> ans = new ArrayDeque<Character>();          //栈
    
            for (int i = 0; i < s.length(); i++) {
            if (visited[s.charAt(i)-'a'] == 1){               //如果栈中已经存在,忽略   
                continue;
            }
            while (!ans.isEmpty()&&ans.peekLast()>s.charAt(i)&&i<lastIndex[ans.peekLast()-'a']){       //如果栈顶元素比待加入的字符 字典序大 ,则看一下该栈顶元素在后面是否还会出现
                char top = ans.removeLast();          //移除栈顶元素      
                visited[top-'a'] = 0;                   //栈顶元素,置为栈中未出现
            }
            ans.addLast(s.charAt(i));                 //将字符串的待加入字符加入栈顶              
            visited[s.charAt(i)-'a'] = 1;                //标志为栈中已存在
            }
    
            StringBuilder stringBuilder = new StringBuilder();
            for (char c:ans){
                stringBuilder.append(c);
            }
    
            return stringBuilder.toString();                     
        }
    }
    
    

    StringBuffer和StringBuilder区别:https://segmentfault.com/a/1190000017909550
    stack:栈 数据是后进先出(LIFO)
    queue:队列 数据是先进先出(FIFO)
    deque:双端队列 数据可以从两端进出

  • 相关阅读:
    Java基础知识
    jQuery的表单操作
    SSM——查询_分页
    jQuery实现查看删除
    SSM之Maven工程的搭建
    Mybatis使用@Param
    Mybatis简单的CURD
    Mybatis使用接口开发
    初入Mybatis
    SQL语句
  • 原文地址:https://www.cnblogs.com/Mr-BING/p/14175995.html
Copyright © 2011-2022 走看看