ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

leetcode 2030. 含特定字母的最小子序列

2021-12-25 14:34:45  阅读:179  来源: 互联网

标签:tmp count int 字母 st result letter 2030 leetcode


特别恶心的一道题
首先基础做法是单调栈,如果没有至少repetition个letter的限制,直接从左往右遍历,维护一个递增栈即可

加上这个限制之后,会有两个改动:

  1. 判断是否当前出栈元素是letter,删除后会导致后面的letter不够凑到repetition,这里需要把原栈的所有元素进行归档(代码31行)
  2. 处理一直是递增字符串的特殊case

代码如下

class Solution {
public:
    string smallestSubsequence(string s, int k, char letter, int repetition) {
        string result;

        int n = s.length();
        stack<char> st;
        int letter_count = 0;

        int need_delete = n - k;
        // int last_repetition = 0;
        

        vector<int> pre(n + 5, 0);
        for(int i = 0; i < n; ++i) {
            if (i == 0) pre[i] = s[i] == letter;
            else pre[i] = pre[i - 1] + (s[i] == letter);
        }
        
        int end_flag = n;

        for(int i = 0; i < n; ++i) {
            int still_have = pre[n - 1] - pre[i] + (s[i] == letter);

            // printf("%d\n", still_have);

            while(!st.empty()) {
                char tt = st.top();

                if (need_delete == 0) break;
                if (tt == letter && letter_count - 1 + still_have < repetition) {
                    string tmp;
                     while(!st.empty()) {
                        tmp += st.top();
                        st.pop();
                    }
                    reverse(tmp.begin(), tmp.end());
                    result += tmp;
                    // printf("%s\n", result.c_str());
                    break;
                }

                if(tt > s[i]) {
                    st.pop();
                    need_delete --;
                    if(tt == letter) letter_count --;
                    // printf("pop %c %d %d\n", tt, need_delete, letter_count);
                } else {
                    break;
                }
            }

            st.push(s[i]);
            if(s[i] == letter) letter_count ++;
            // printf("push %c %d %d\n", s[i], need_delete, letter_count);
        }


        string tmp;
        while(!st.empty()) {
            tmp += st.top();
            st.pop();
        }
        reverse(tmp.begin(), tmp.end());
        result += tmp;

        // printf("%s\n", result.c_str());

        
        result = result.substr(0, k);

        // for special case
        int cnt = 0;
        for(int i = 0; i < k; ++i) {
            if(result[i] == letter) {
                cnt ++;
            }
        }
        for(int i = k - 1; i >= 0; --i) {
            if(result[i] != letter && cnt < repetition) {
                result[i] = letter;
                cnt ++;
            }
        }

        return result;
    }
};

标签:tmp,count,int,字母,st,result,letter,2030,leetcode
来源: https://www.cnblogs.com/Basasuya/p/15730436.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有