OAmaster
— / 2已做

Given a string input_str of length n, choose any character that occurs at least twice and delete any one occurrence. Repeat this until all remaining characters are distinct. Return the lexicographically maximum string that can be formed this way. Function Description Complete the function getString in the editor below. getString has the following parameters:

  • string input_str: a string of length n Returns string: the result of the operations, as described

Constraints

  • input_str contains only lowercase English letters
  • 1 ≤ n ≤ 10⁵

Example 1

Input:

input_str = "aabcb"

Output:

"acb"

Explanation: The length of the string, n = 5. Some of the strings that can be formed are:

  • "acb" - delete the first occurrences of 'a' and 'b'
  • "abc" - delete the first occurrence of 'a' and the second occurrence of 'b' It can be proven that the lexicographically maximum string that can be obtained is "acb".

解法

字典序最大且字符全部互不相同 ⇒ 单调栈贪心。维护栈和 in_stack 集合 + 剩余字符计数。遍历字符 c:若已在栈内则该字符剩余计数 - 1 后跳过;否则在栈顶字符 t < ct 还会在后面出现时弹出 t,最后入栈。复杂度 O(n),空间 O(σ)

from collections import Counter

def get_string(input_str: str) -> str:
    remain = Counter(input_str)
    in_stk = set()
    stk = []
    for c in input_str:
        if c in in_stk:
            remain[c] -= 1
            continue
        while stk and stk[-1] < c and remain[stk[-1]] > 1:
            top = stk.pop()
            in_stk.remove(top)
            remain[top] -= 1
        stk.append(c)
        in_stk.add(c)
    return "".join(stk)
class Solution {
    String getString(String inputStr) {
        int[] remain = new int[26];
        for (char c : inputStr.toCharArray()) remain[c - 'a']++;
        boolean[] inStk = new boolean[26];
        StringBuilder stk = new StringBuilder();
        for (char c : inputStr.toCharArray()) {
            if (inStk[c - 'a']) { remain[c - 'a']--; continue; }
            while (stk.length() > 0 && stk.charAt(stk.length() - 1) < c
                   && remain[stk.charAt(stk.length() - 1) - 'a'] > 1) {
                char top = stk.charAt(stk.length() - 1);
                stk.deleteCharAt(stk.length() - 1);
                inStk[top - 'a'] = false;
                remain[top - 'a']--;
            }
            stk.append(c);
            inStk[c - 'a'] = true;
        }
        return stk.toString();
    }
}
class Solution {
public:
    string getString(string inputStr) {
        int remain[26] = {0};
        for (char c : inputStr) remain[c - 'a']++;
        bool inStk[26] = {false};
        string stk;
        for (char c : inputStr) {
            if (inStk[c - 'a']) { remain[c - 'a']--; continue; }
            while (!stk.empty() && stk.back() < c && remain[stk.back() - 'a'] > 1) {
                char top = stk.back();
                stk.pop_back();
                inStk[top - 'a'] = false;
                remain[top - 'a']--;
            }
            stk.push_back(c);
            inStk[c - 'a'] = true;
        }
        return stk;
    }
};

A binary string is a string consisting only of 0s and 1s. A substring is a contiguous group of characters within a string. Given a binary string, find the number of substrings that contain an equal number of 0s and 1s and all the 0s and 1s are grouped together. Note that duplicate substrings are also counted in the answer. For example, '0011' has two overlapping substrings that meet the criteria: '0011' and '01'. Function Description Complete the function getSubstringCount in the editor. getSubstringCount has the following parameter(s):

  • s: String: a binary string Returns int: the number of substrings that meet the criteria

Constraints

  • 1 ≤ length of s ≤ 10⁵
  • The string s consists of 0s and 1s only.

Example 1

Input:

s = "011001"

Output:

4

Explanation: The substrings "01", "10", "1100", and "01" have equal numbers of 0s and 1s with all 0s and 1s grouped consecutively. Hence, the answer is 4. Note that the substring "0110" has an equal number of 0s and 1s but is not counted because not all 0s and 1s are grouped together.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁
Pro 会员

解锁全部 1 道题的解法

题面你已经看到了 — 解法 + 三语代码 + 复杂度推导 + 边界讨论, Pro 解锁.

Pro 解锁全部
  • 📚1000+ 道真实北美 OA, Python / Java / C++ 三语题解
  • 📊个人 dashboard + 进度可视化 + 14 天活跃图
  • 📝题目笔记跨设备同步 + 个人复盘库
  • 🔓随时取消下次续费, Stripe Customer Portal 自助管理
$12/月($98/年, 一次付清省 32%)

≈ 北美 SWE 工资 10 分钟 · LeetCode Premium $35/月 的 23%