【每日算法Day 100】字节跳动 AI Lab 面试编程题(三道)

简介: 【每日算法Day 100】字节跳动 AI Lab 面试编程题(三道)

今天连着面了两次字节跳动,勉强撑到了明天三面。一共三道编程题,做的很烂,这里分享一下。

第一题

给出一条长度为 L 的线段,除了头和尾两个点以外,上面还有 n 个整数点,需要在上面再放 k 个新的点,使得相邻的两个点之间的最大距离最小,求这个最小的距离。

题解

我当时太紧张了,真是脑抽了,还想着弄个优先队列,划分最大的,然后丢进去,再划分最大的,但是是错的。

正确解法小姐姐走了我才想起来,二分答案 m ,然后扫描一遍判断将每一段划分成小于等于 m 的一共需要多少次。如果次数大于 k ,说明 m 太短了,否则说明 m 太长了。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    int L, n, k;
    scanf("%d%d%d", &L, &n, &k);
    vector<int> a(n+2, 0);
    a[0] = 1;
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    a[n+1] = L;
    int l = 1, r = L-1;
    while (l < r) {
        int m = l + (r - l) / 2;
        int cnt = 0;
        for (int i = 1; i <= n+1; ++i) {
            cnt += (a[i] - a[i-1] - 1) / m;
        }
        if (cnt > k) l = m + 1;
        else r = m;
    }
    cout << l << endl;
    return 0;
}

第二题

给出一个数组 A,找到最大的 A[i] - A[j],要求 i > j

题解

这题很简单,直接遍历每个 A[i],维护它前面最小的那个数 minn,然后求出最大的 A[i] - minn 就行了。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n;
    scanf("%d", &n);
    vector<int> a(n, 0);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    int minn = a[0], res = INT_MIN;
    for (int i = 1; i < n; ++i) {
        res = max(res, a[i]-minn);
        minn = min(minn, a[i]);
    }
    cout << res << endl;
}

第三题

给定一个字符串,对该字符串进行删除操作,保留 k 个字符且相对位置不变,使字典序最小。

题解

这题也脑抽了,想了一堆方法,dp 复杂度太高,线段树太麻烦,最后用 map 勉强写了一下。

主要思想是这样的,最后要保留 k 个字符,那么第一个字符只能在下标 0 ~ n-k 中寻找,那肯定找最小的啊,如果有多个就找最前面那个,把它的位置记为 pos

然后第二个字符肯定得在下标 pos ~ n-k+1 中寻找,还是一样的思路,找到以后更新 pos 位置,依次找下去找到 k 个为止。

所以我就利用了 map 的特性,把寻找窗口内的字符个数做一下统计,然后取出 map 中的第一个字符就是字典序最小的了,次数减一,如果减到 0 了就删除掉。

然后从 pos 位置开始遍历,直到第一个等于你刚刚取出的字符为止,更新 pos 位置。

最终的时间复杂度是  ,可以直接看作  。

最优解:

最优解当时没想出来,是用单调栈。维护一个递增的单调栈,我们的目标是保留 k 个字符,也就是删除 n-k 个字符。

那么如果栈顶元素大于当前遍历元素,并且还没删够 n-k 个,就出栈,当作删除了一个元素。否则的话如果删够了,不管大小关系统统入栈,因为你没法删了。

最后全遍历完了,如果还没删够,那就继续出栈,直到删够为止。最后把栈里的字符拼接成一个字符串就是答案了。

时间复杂度是  的。

代码

#include <bits/stdc++.h>
using namespace std;
string f(string s, int k) {
    int n = s.size();
    map<char, int> mp;
    for (int i = 0; i <= n-k; ++i) {
        mp[s[i]]++;
    }
    string res = "";
    int pos = 0;
    for (int i = k; i >= 1; --i) {
        char c = mp.begin()->first;
        res += c;
        for (int j = pos; j <= n-i; ++j) {
            mp[s[j]]--;
            if (!mp[s[j]]) mp.erase(s[j]);
            if (s[j] == c) {
                pos = j + 1;
                break;
            }
        }
        if (i == 1) break;
        mp[s[n-i+1]]++;
    }
    return res;
}
int main() {
    string s;
    int k;
    cin >> s >> k;
    cout << f(s, k) << endl;
}

最优解:

#include <bits/stdc++.h>
using namespace std;
string f(string s, int k) {
    int n = s.size();
    k = n - k;
    stack<char> st;
    for (int i = 0; i < n; ++i) {
        while (!st.empty() && st.top() > s[i] && k) {
            st.pop();
            k--;
        }
        st.push(s[i]);
    }
    string res = "";
    while (!st.empty()) {
        if (k) k--;
        else res += st.top();
        st.pop();
    }
    reverse(res.begin(), res.end());
    return res;
}
int main() {
    string s;
    int k;
    cin >> s >> k;
    cout << f(s, k) << endl;
}
相关文章
|
23天前
|
机器学习/深度学习 人工智能 自然语言处理
算法金 | AI 基石,无处不在的朴素贝叶斯算法
```markdown 探索贝叶斯定理:从默默无闻到AI基石。18世纪数学家贝叶斯的理论,初期未受重视,后成为20世纪机器学习、医学诊断和金融分析等领域关键。贝叶斯定理是智能背后的逻辑,朴素贝叶斯分类器在文本分类等应用中表现出色。贝叶斯网络则用于表示变量间条件依赖,常见于医学诊断和故障检测。贝叶斯推理通过更新信念以适应新证据,广泛应用于统计和AI。尽管有计算复杂性等局限,贝叶斯算法在小数据集和高不确定性场景中仍极具价值。了解并掌握这一算法,助你笑傲智能江湖! ```
29 2
算法金 | AI 基石,无处不在的朴素贝叶斯算法
|
5天前
|
算法 Java 调度
《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)
《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)
14 0
|
28天前
|
消息中间件 算法 Java
抖音面试:说说延迟任务的调度算法?
Netty 框架是以性能著称的框架,因此在它的框架中使用了大量提升性能的机制,例如 Netty 用于实现延迟队列的时间轮调度算法就是一个典型的例子。使用时间轮调度算法可以实现海量任务新增和取消任务的时间度为 O(1),那么什么是时间轮调度算法呢?接下来我们一起来看。 ## 1.延迟任务实现 在 Netty 中,我们需要使用 HashedWheelTimer 类来实现延迟任务,例如以下代码: ```java public class DelayTaskExample { public static void main(String[] args) { System.ou
29 5
抖音面试:说说延迟任务的调度算法?
|
5天前
|
机器学习/深度学习 人工智能 自然语言处理
算法金 | 没有思考过 Embedding,不足以谈 AI
**摘要:** 本文深入探讨了人工智能中的Embedding技术,解释了它是如何将高维数据映射到低维向量空间以简化处理和捕获内在关系的。文章介绍了词向量、图像嵌入和用户嵌入等常见类型的Embedding,并强调了其在自然语言处理、计算机视觉和推荐系统中的应用。此外,还讨论了Embedding的数学基础,如向量空间和线性代数,并提到了Word2Vec、GloVe和BERT等经典模型。最后,文章涵盖了如何选择合适的Embedding技术,以及在资源有限时的考虑因素。通过理解Embedding,读者能够更好地掌握AI的精髓。
6 0
算法金 | 没有思考过 Embedding,不足以谈 AI
|
11天前
|
机器学习/深度学习 人工智能 编解码
AI - 支持向量机算法
**支持向量机(SVM)**是一种用于二分类的强大学习算法,寻找最佳超平面以最大化类别间间隔。对于线性可分数据,SVM通过硬间隔最大化找到线性分类器;非线性数据则通过核技巧映射到高维空间,成为非线性分类器。SVM利用软间隔处理异常或线性不可分情况,并通过惩罚参数C平衡间隔和误分类。损失函数常采用合页损失,鸢尾花数据集常用于SVM的示例实验。
|
11天前
|
机器学习/深度学习 人工智能 Dart
AI - 机器学习GBDT算法
梯度提升决策树(Gradient Boosting Decision Tree),是一种集成学习的算法,它通过构建多个决策树来逐步修正之前模型的错误,从而提升模型整体的预测性能。
|
21天前
|
机器学习/深度学习 算法 搜索推荐
编程之舞:探索算法的优雅与力量
【6月更文挑战第10天】在软件的世界里,算法是构筑数字宇宙的基石。它们如同精心编排的舞蹈,每一个步骤都充满着逻辑的美感和解决问题的力量。本文将带领读者走进算法的世界,一起感受那些精妙绝伦的编程思想如何转化为解决现实问题的钥匙。
18 3
|
6天前
|
安全 Java API
《面试专题-----经典高频面试题收集三》解锁 Java 面试的关键:深度解析并发编程基础篇高频经典面试题(第三篇)
《面试专题-----经典高频面试题收集三》解锁 Java 面试的关键:深度解析并发编程基础篇高频经典面试题(第三篇)
11 0
|
9天前
|
人工智能 算法 搜索推荐
Java算法编程详解和程序实例
Java算法编程详解和程序实例
14 0
|
9天前
|
机器学习/深度学习 人工智能 自然语言处理
AI大模型的核心成功因素通常可以归结为三大要素:大数据、大算力和强算法。
AI大模型的核心成功因素通常可以归结为三大要素:大数据、大算力和强算法。
24 0