临时毁offer!大厂可真叫我开眼界。。

462ee3ba724fc8d33b3c9857e37cc9ec.gif

精品推荐:

《征服数据结构》《经典图论算法》

一网友发文称:成功进入DY的面试流程,一面二面三面都已通过,背调也通过,已经在走offer环节,hr突然说因为薪资被卡,offer不能发了。

如果没有背调环节,不发offer很正常,这种情况下一般都是三面没通过。像薪资待遇,社保,工作时间安排,即便是不通过有时候hr也会说的,我之前就遇到过不少,给我说了一大堆,最后还是没发offer,她可能也在挑。

但是都已经参加背调,并且背调通过了还不发offer,这个就少见了。所以只要不发offer,一切的许诺都是假的。即便是发了offer,也有违约的情况。

529e801630be8cb032e1ece1b4746e20.png

网友评论:

31d436efcdec10e5048fa26deffa83e5.png

--------------下面是今天的算法题--------------

来看下今天的算法题,这题是LeetCode的第316题:去除重复字母。

问题描述

来源:LeetCode第316题

难度:中等

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

示例1:

输入:s = "bcabc"

输出:"abc"

示例2:

输入:s = "cbacdcbc"

输出:"acdb"

  • 1 <= s.length <= 10^4

  • s 由小写英文字母组成

问题分析

这题是让删除字符串 s 中的重复字符,使每个字符只出现一次,需要保证返回结果的字典序最小,并且还不能打乱字符的相对位置。

解决思路就是使用一个栈,然后遍历字符串中的每个字符,如果当前字符在栈中已经出现了就不用管了,因为每个字符只能出现一次。

如果当前字符在栈中没有出现,我们就需要把他添加到栈中,添加的时候因为要保证字典序最小,所以要和栈顶元素比较,如果当前字符比栈顶元素小并且栈顶元素在后面还会出现,我们就把栈顶元素给删除,接着继续执行上面的步骤。

举个例子,比如栈中元素是[a,b,f](右边是栈顶),当我们添加字符 c 的时候,因为栈顶字符 f 比当前字符 c 大:

1,假设字符串后面还有 f ,这个时候我们就可以把 f 给移除掉,在后面的时候可以在加 f 。

2,假设字符串后面没有 f 了,就不能把字符 f 给移除,因为移除之后,后面没有了就没法在添加了。

这里的关键点是怎么判断后面还有没有待移除的字符呢?很简单,我们只需要在开始的时候计算每个字符的个数即可,用掉一个就减去一个。最后栈中的字符就是需要返回的结果,我们还需要把他转化为字符串。

JAVA:

public String removeDuplicateLetters(String s) {
    Stack<Character> stk = new Stack<>();// 栈
    int[] count = new int[128];// 统计每个字符的数量
    for (int i = 0; i < s.length(); i++)
        count[s.charAt(i)]++;
    // 记录对应的字符有没有添加到栈中
    boolean[] add = new boolean[128];
    for (char ch : s.toCharArray()) {
        count[ch]--;// 遍历到当前字符,数量要减1
        if (add[ch])// 如果当前字符已经添加到栈中就跳过
            continue;
        // 如果当前字符没有添加到栈中,栈顶字符比当前字符大
        // 并且栈顶字符在后面还有,就让栈顶字符出栈。
        while (!stk.isEmpty() && stk.peek() > ch
                && count[stk.peek()] > 0) {
            add[stk.pop()] = false;// 标记为false
        }
        stk.push(ch);// 把当前字符添加到栈中
        add[ch] = true;
    }
    // 这里是把栈中的字符转化为字符串。
    StringBuilder sb = new StringBuilder();
    while (!stk.isEmpty())
        sb.append(stk.pop());
    return sb.reverse().toString();
}

C++:

public:
    string removeDuplicateLetters(string s) {
        stack<char> stk;// 栈
        vector<int> count(128);// 统计每个字符的数量
        for (char ch: s)
            count[ch]++;
        // 记录对应的字符有没有添加到栈中
        vector<bool> add(128, false);
        for (char ch: s) {
            count[ch]--;// 遍历到当前字符,数量要减1
            if (add[ch])// 如果当前字符已经添加到栈中就跳过
                continue;
            // 如果当前字符没有添加到栈中,栈顶字符比当前字符大
            // 并且栈顶字符在后面还有,就让栈顶字符出栈。
            while (!stk.empty() && stk.top() > ch && count[stk.top()] > 0) {
                add[stk.top()] = false;
                stk.pop();
            }
            stk.push(ch);// 把当前字符添加到栈中
            add[ch] = true;
        }

        // 这里是把栈中的字符转化为字符串。
        string str;
        while (!stk.empty()) {
            str.push_back(stk.top());
            stk.pop();
        }
        reverse(str.begin(), str.end());
        return str;
    }

C:

char *removeDuplicateLetters(char *s) {
    int count[128] = {0};// 统计每个字符的数量
    for (int i = 0; i < strlen(s); i++)
        count[s[i]]++;
    char stk[260];// 栈
    int index = 0;// 栈中元素的指针
    // 记录对应的字符有没有添加到栈中
    bool add[128] = {false};
    char ch = 0;
    for (int i = 0; (ch = s[i]) != '\0'; i++) {
        count[ch]--;// 遍历到当前字符,数量要减1
        if (add[ch])// 如果当前字符已经添加到栈中就跳过
            continue;
        // 如果当前字符没有添加到栈中,栈顶字符比当前字符大
        // 并且栈顶字符在后面还有,就让栈顶字符出栈。
        while (index > 0 && stk[index - 1] > ch && count[stk[index - 1]] > 0) {
            add[stk[--index]] = false;// 标记为false
        }
        stk[index++] = ch;// 把当前字符添加到栈中
        add[ch] = true;
    }
    char *ans = malloc((index + 1) * sizeof(char));
    // 这里是把栈中的字符转化为字符串。
    for (int i = 0; i < index; ++i)
        ans[i] = stk[i];
    ans[index] = '\0';
    return ans;
}

Python:

def removeDuplicateLetters(self, s: str) -> str:
    stk = []  # 栈
    count = Counter(s)  # 统计每个字符的数量
    # 记录对应的字符有没有添加到栈中
    add = [0] * 128
    for ch in s:
        count[ch] -= 1  # 遍历到当前字符,数量要减1
        if add[ord(ch)]:  # 如果当前字符已经添加到栈中就跳过
            continue
            '''
             如果当前字符没有添加到栈中,栈顶字符比当前字符大
            并且栈顶字符在后面还有,就让栈顶字符出栈。
            '''
        while stk and stk[-1] > ch and count[stk[-1]] > 0:
            add[ord(stk[-1])] = 0  # 标记为false
            stk.pop()
        stk.append(ch)  # 把当前字符添加到栈中
        add[ord(ch)] = 1
        # 这里是把栈中的字符转化为字符串。
    return ''.join(stk)

bec2f0e3bbde35998007780bce95db2c.gif

笔者简介

博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据结构和算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值