单调栈真的懂了呀系列《不同字符的最小子序列》

141 阅读2分钟

价值:记录学习过程的思考,本身就是一场动态规划的前生,记忆化搜索。

单调栈:及时去掉无用数据,保证栈中数据有序。

Problem: 1081. 不同字符的最小子序列

思路

讲述看到这一题的思路 暴力做法:统计(为了去重字符,得到有效字符)->全排列(有效字符生成字串)->顺序依赖([i,j原串、单个字串]依赖原来顺序,判别字串有效,有效条件单个字串判断完了j==字串n-1索引),取结果

单调栈:枚举到的当前元素与栈顶元素决策,考虑入栈还是枚举出栈。

学习到的思路:

有顺序依赖,除了双指针对比遍历,可以考虑栈顶入栈时比较进行维护,轻量级维护有序,扩大范围。。。

Code

class Solution {
    public String smallestSubsequence(String s) {
            int n = s.length();

            char[] chars = s.toCharArray();
            //顺序覆盖,记录元素最后出现的索引位置
            int[] lastIndex = new int[26];
            for(int i = 0; i<chars.length;i++){
                lastIndex[chars[i]-'a'] = i;
            }

            Deque<Character> stack = new ArrayDeque<>();
            //记录下访问过没有 {true,false...26}
            boolean[] visited = new boolean[26];
            for(int i =0 ; i < n ; i++){

                //如果之前访问过了,后边再次看到,直接跳过了,because,前边已经放到了正确的位置上===单调位置
                if(visited[chars[i] - 'a']){
                    continue;
                }

                //栈里边有元素 && 栈顶元素大于遍历到的元素 && 栈顶元素后续还能看到 ===》 弹栈,当前小元素入栈
                while(!stack.isEmpty() && stack.peekLast() > chars[i] && lastIndex[stack.peekLast() - 'a']>i){
                    Character top = stack.pollLast();
                    visited[top - 'a'] = false;
                }

                //一般朴素情况,便利到的元素添加到栈内
                stack.addLast(chars[i]);
                visited[chars[i] - 'a'] = true;
            }

            StringBuilder sb = new StringBuilder();
            for(char c : stack){
                sb.append(c);
            }

            return sb.toString();

        }
}
//暴力
public String smallestSubsequence(String s) {
            int n = s.length();

            char[] chars = s.toCharArray();

            // quchong
            int[] scount = new int[26];
            for(int i = 0; i<chars.length;i++){
                scount[chars[i]-'a']++;
            }

            //
            List<Character> arr = new ArrayList();
            for(int i =0; i< 26 ; i++){
                if(char[i]>0){
                    arr.add(char[i] + 'a');
                }
            }

            //gen quan pai lie
            List<String> ans = new ArrayList<>();
            ans = dfs(arr.toArray(),0,new StringBuilder(),ans);

            //s[0~i] && 
            for(String an : ans){
                int j = 0;
                int i = 0; 
                while(i<s.length && j < an.length){
                    if(an == s.charAt[i]){
                        i++;
                        j++;
                    }
                    else
                    {
                        i++;
                    }
                    if(j == an.length-1) return an;
                }
            }
        }

    public void dfs(char[] haveChars, int index, StringBuilder appender, List<String> res) {
        if (index == haveChars.length) {
            // youxiao == > res
            res.add(appender.toString());
        }

        char cc = haveChars[index];

        // xuan

        // buxuan
    }