抖音 UG 社招一面算法原题

news2025/1/22 16:08:23

史上最严热点新机制

或许是受到前段时间「巴黎丢作业」的影响,抖音近日(5月27日)实施了新的热点内容核实机制。

具体来说,若用户在抖音以热点事件当事人身份发声,抖音将联系当事人进行身份认证。

逾期未认证的用户,抖音将采取包括强提醒标注、禁言等一系列措施,直至用户提供可信材料。

同时,对于演绎类内容,抖音要求发布者必须显著标注"虚构演绎"声明,对于部分疑似摆拍的热点内容,抖音称将主动请求各地相关部门核实或联动各地新闻机构调查。

如此一来,基本上是把"造谣骗流量"的车门焊死了,但这也将大大增加抖音方面的运营成本。

个人感觉:初心很好,但如果严格按照上述说的来做,其实很难达到好的效果。

从以前的「纯算法」到现在的「人工介入」,以及认证材料的合理性,再到标记的及时性,都可能会让内容平台呈现的效果大打折扣。

要知道,一个视频如果因为新规则晚了半天进入流量池,可能就已经错过了最佳传播时间了。

而且任何打击类的新规则,也都无法避免的误伤问题。

对于抖音提出的「史上最严热点新机制」,你怎么看?

...

回归主题。

来一道和「字节跳动」相关的题目。

题目描述

平台:LeetCode

题号:907

给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围为 arr 的每个(连续)子数组。

由于答案可能很大,因此 返回答案模

示例 1:

输入:arr = [3,1,2,4]

输出:17

解释:
子数组为 [3],[1],[2],[4],[3,1],[1,2],[2,4],[3,1,2],[1,2,4],[3,1,2,4]。 
最小值为 3,1,2,4,1,1,2,1,1,1,和为 17。

示例 2:

输入:arr = [11,81,94,43,3]

输出:444

提示:

单调栈 + 数学

原问题为求所有子数组的最小值之和。

统计所有子数组需要枚举左右端点,复杂度为 ,对于每个子数组,我们还需要通过线性扫描的方式找到其最小值,复杂度为 ,因此朴素解法的整体复杂度为 ,题目给定数据范围为 ,会 TLE

由于我们是从子数组中取最小值来进行累加,即参与答案构成的每个数必然某个具体的

「因此我们可以将原问题转化为「考虑统计每个 对答案的贡献」。」

对于某一个 而言,我们考虑其能够作为哪些子数组的最小值。

我们可以想象以 为中心,分别往两端进行拓展,只要新拓展的边界不会改变「 为当前子数组的最小值」的性质即可。

换句话说,我们需要找到 作为最小值的最远左右边界,即找到 左右最近一个比其小的位置 lr

「在给定序列中,找到任意 最近一个比其大/小的位置,可使用「单调栈」进行求解。」

到这里,我们会自然想到,通过单调栈的方式,分别预处理除 lr 数组:

  • l[i] = loc 含义为下标 i 左边最近一个比 arr[i] 小的位置是 loc(若在 左侧不存在比其小的数,则 loc = -1
  • r[i] = loc 含义为下标 i 右边最近一个比 arr[i] 小的位置是 loc(若在 左侧不存在比其小的数,则 loc = n

当我们预处理两数组后,通过简单「乘法原理」即可统计以 为最小值时,子数组的个数:

  • 包含 的子数组左端点个数为
  • 包含 的子数组右端点个数为

子数组的个数 X 子数组最小值 ,即是当前 对答案的贡献:

「统计所有 对答案的贡献即是最终答案,但我们忽略了「当 arr 存在重复元素,且该元素作为子数组最小值时,最远左右端点的边界越过重复元素时,导致重复统计子数组」的问题。」

我们不失一般性的举个 🌰 来理解(下图):

alt

为了消除这种重复统计,我们可以将「最远左右边界」的一端,从「严格小于」调整为「小于等于」,从而实现半开半闭的效果。

Java 代码:

class Solution {
    int MOD = (int)1e9+7;
    public int sumSubarrayMins(int[] arr) {
        int n = arr.length, ans = 0;
        int[] l = new int[n], r = new int[n];
        Arrays.fill(l, -1); Arrays.fill(r, n);
        Deque<Integer> d = new ArrayDeque<>();
        for (int i = 0; i < n; i++) {
            while (!d.isEmpty() && arr[d.peekLast()] >= arr[i]) r[d.pollLast()] = i;
            d.addLast(i);
        }
        d.clear();
        for (int i = n - 1; i >= 0; i--) {
            while (!d.isEmpty() && arr[d.peekLast()] > arr[i]) l[d.pollLast()] = i;
            d.addLast(i);
        }
        for (int i = 0; i < n; i++) {
            int a = i - l[i], b = r[i] - i;
            ans += a * 1L * b % MOD * arr[i] % MOD;
            ans %= MOD;
        }
        return ans;
    }
}

C++ 代码:

class Solution {
public:
    int MOD = 1e9 + 7;
    int sumSubarrayMins(vector<int>& arr) {
        int n = arr.size(), ans = 0;
        vector<intl(n, -1)r(n, n);
        stack<int> d;
        for (int i = 0; i < n; i++) {
            while (!d.empty() && arr[d.top()] >= arr[i]) {
                r[d.top()] = i;
                d.pop();
            }
            d.push(i);
        }
        while (!d.empty()) d.pop();
        for (int i = n - 1; i >= 0; i--) {
            while (!d.empty() && arr[d.top()] > arr[i]) {
                l[d.top()] = i;
                d.pop();
            }
            d.push(i);
        }
        for (int i = 0; i < n; i++) {
            long long a = i - l[i], b = r[i] - i;
            ans = (ans + a * b % MOD * arr[i] % MOD) % MOD;
        }
        return ans;
    }
};

Python 代码:

class Solution:
    def sumSubarrayMins(self, arr: List[int]) -> int:
        n, ans = len(arr), 0
        l, r = [-1] * n, [n] * n
        stk = []
        for i in range(n):
            while stk and arr[stk[-1]] >= arr[i]:
                r[stk.pop()] = i
            stk.append(i)
        stk = []
        for i in range(n - 1-1-1):
            while stk and arr[stk[-1]] > arr[i]:
                l[stk.pop()] = i
            stk.append(i)
        for i in range(n):
            a, b = i - l[i], r[i] - i
            ans += a * b * arr[i]
        return ans % (10 ** 9 + 7)

TypeScript 代码:

const MOD = 1000000007
function sumSubarrayMins(arr: number[]): number {
    let n = arr.length, ans = 0
    const l = new Array<number>(n).fill(-1), r = new Array<number>(n).fill(n)
    const stk = new Array<number>(n).fill(0)
    let he = 0, ta = 0
    for (let i = 0; i < n; i++) {
        while (he < ta && arr[stk[ta - 1]] >= arr[i]) r[stk[--ta]] = i
        stk[ta++] = i
    }
    he = ta = 0
    for (let i = n - 1; i >= 0; i--) {
        while (he < ta && arr[stk[ta - 1]] > arr[i]) l[stk[--ta]] = i
        stk[ta++] = i
    }
    for (let i = 0; i < n; i++) {
        const a = i - l[i], b = r[i] - i
        ans += a * b % MOD * arr[i] % MOD
        ans %= MOD
    }
    return ans
}
  • 时间复杂度:
  • 空间复杂度:

优化

实际上,当我们从栈中弹出某个 时,其右边界必然是导致其弹出的 arr[r](当前所遍历到的元素),而 若存在左边界,必然是位于 栈中的前一位置,即 弹出后的新栈顶元素(若不存在物理左边界,则左边界为 )。

Java 代码:

class Solution {
    int MOD = (int)1e9+7;
    public int sumSubarrayMins(int[] arr) {
        int n = arr.length, ans = 0;
        Deque<Integer> d = new ArrayDeque<>();
        for (int r = 0; r <= n; r++) {
            int t = r < n ? arr[r] : 0;
            while (!d.isEmpty() && arr[d.peekLast()] >= t) {
                int cur = d.pollLast();
                int l = d.isEmpty() ? -1 : d.peekLast();
                int a = cur - l, b = r - cur;
                ans += a * 1L * b % MOD * arr[cur] % MOD;
                ans %= MOD;
            }
            d.addLast(r);
        }
        return ans;
    }
}

C++ 代码:

class Solution {
public:
    int MOD = 1e9 + 7;
    int sumSubarrayMins(vector<int>& arr) {
        int n = arr.size(), ans = 0;
        deque<int> d;
        for (int r = 0; r <= n; r++) {
            int t = (r < n) ? arr[r] : 0;
            while (!d.empty() && arr[d.back()] >= t) {
                int cur = d.back();
                d.pop_back();
                int l = d.empty() ? -1 : d.back();
                long long a = cur - l, b = r - cur;
                ans = (ans + a * b % MOD * arr[cur] % MOD) % MOD;
            }
            d.push_back(r);
        }
        return ans;
    }
};

Python 代码:

class Solution:
    def sumSubarrayMins(self, arr: List[int]) -> int:
        n, ans = len(arr), 0
        stk = []
        for r in range(n + 1):
            t = arr[r] if r < n else 0
            while stk and arr[stk[-1]] >= t:
                cur = stk.pop()
                l = stk[-1if stk else -1
                a, b = cur - l, r - cur
                ans += a * b * arr[cur]
            stk.append(r)
        return ans % (10 ** 9 + 7)

TypeScript 代码:

const MOD = 1000000007
function sumSubarrayMins(arr: number[]): number {
    let n = arr.length, ans = 0
    const stk = new Array<number>(n).fill(0)
    let he = 0, ta = 0
    for (let r = 0; r <= n; r++) {
        const t = r < n ? arr[r] : 0
        while (he < ta && arr[stk[ta - 1]] >= t) {
            const cur = stk[--ta]
            const l = he < ta ? stk[ta - 1] : -1
            const a = cur - l, b = r - cur
            ans += a * b % MOD * arr[cur] % MOD
            ans %= MOD
        }
        stk[ta++] = r
    }
    return ans
}
  • 时间复杂度:
  • 空间复杂度:

最后

给大伙通知一下 📢 :

全网最低价 LeetCode 会员目前仍可用 ~

📅 年度会员:有效期加赠两个月!!; 季度会员:有效期加赠两周!!

🧧 年度会员:获 66.66 现金红包!!; 季度会员:获 22.22 现金红包!!

🎁 年度会员:参与当月丰厚专属实物抽奖(中奖率 > 30%)!!

专属链接:leetcode.cn/premium/?promoChannel=acoier

我是宫水三叶,每天都会分享算法知识,并和大家聊聊近期的所见所闻。

欢迎关注,明天见。

更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1719126.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

13.优化界面化的游戏辅助

12.使用mfc实现游戏辅助的界面 在它的代码上进行修改 12.使用mfc实现游戏辅助的界面它的代码是频繁读写游戏的内存&#xff0c;这样不是很好&#xff0c;下面的代码是在它的基础上进行了封装&#xff0c;控制无敌的逻辑在我们申请的内存中实现&#xff08;也就是在一个全局中实…

连锁收银系统的五大功能 会员营销是核心

连锁企业的收银系统是其经营管理的关键工具之一&#xff0c;具备多种功能可以帮助企业提高效率、优化服务并实现会员营销。以下是连锁收银系统的五大功能&#xff0c;其中会员营销作为核心功能将在最后详细讨论。 首先&#xff0c;收银系统应具备高效的销售管理功能。这包括商品…

为了新来的扫地机器人,我差点把自家狗子给扔了

文 | 螳螂观察 作者 | 凯乐 作为一个大龄未婚男青年&#xff0c;我承认&#xff0c;我很懒。 有多懒&#xff1f;就连用来偷懒的扫地机器人我也一直懒得去买。 要不是朋友实在看不下去&#xff0c;在前不久生日时送了我一台二手扫地机器人&#xff08;没错&#xff0c;是他…

重发布——重分布——重分发

作用: 在两种路由协议间&#xff0c;或者同种协议的不同进程间;构建一台ASBR&#xff0c;同时工作在两种协议或两个进程中&#xff0c;学习到两端所有的路由条目后&#xff0c;进行路由共享&#xff0c;实现全网可达; 条件&#xff1a; 1、必须存在ASBR--ASBR自治系统边界路…

tinycudann安装

在安装完torch等 直接运行下面的指令会出现错误 pip install githttps://github.com/NVlabs/tiny-cuda-nn/#subdirectorybindings/torch大部分错误是下面的 大概看了一下都是因为虚拟环境里面的include文件下缺少文件&#xff0c;将之前的一些.h文件全部复制过来在执行上面的…

基础—SQL—DQL(数据查询语言)分组查询

一、引言 分组查询的关键字是&#xff1a;GROUP BY。 二、DQL—分组查询 1、语法 SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后过滤条件 ]; 注意&#xff1a; 1、[ ] 里的内容可以有可以没有。 2、这条SQL语句有两块指定条件的地方&#…

Playwright 自动化操作

之前有见同事用过playwright进行浏览器模拟操作&#xff0c;但是没有仔细了解&#xff0c;今天去详细看了下&#xff0c;发现playwright着实比selenium牛逼多了 Playwright 相对于selenium优点 1、自动下载chromnium, 无需担心chrome升级对应版本问题&#xff1b; 2、支持录屏操…

【UE5.1 角色练习】09-物体抬升、抛出技能 - part1

前言 在上一篇&#xff08;【UE5.1 角色练习】08-传送技能&#xff09;的基础上继续实现控制物体抬升、抛出的功能。 效果 步骤 一、准备技能动画 1. 在项目设置中新建一个操作映射&#xff0c;这里命名为“Skill_GravityControl”&#xff0c;用按键4触发 2. 通过IK重定向…

【UE5:CesiumForUnreal】——加载无高度地形数据

目录 1.实现目的 2.数据准备 2.1下载数据 2.2 数据切片 3.加载无地形数据 1.实现目的 在CesiumForUnreal插件中&#xff0c;我们加载地图和地形图层之后&#xff0c;默认都是加载的带有高程信息的地形数据&#xff0c;在实际的项目和开发中&#xff0c;有时候我们需要加载无…

使用QtCreator C++编写串口调试助手

100编程书屋_孔夫子旧书网 1.首先看一下我设计的界面&#xff08;我这里比较简单&#xff0c;大家可根据自己的需求进行设计&#xff09; &#xff08;界面设计的过程中&#xff0c;每一个控件的名称最好进行修改&#xff0c;便于后续控件太多不好区分&#xff0c;给控件命名的…

《中国科技纵横》是什么级别的期刊?是正规期刊吗?能评职称吗?

问题解答&#xff1a; 问&#xff1a;《中国科技纵横》期刊是核心吗&#xff1f; 答&#xff1a;不是&#xff0c;是万方维普收录的正规期刊。 问&#xff1a;《中国科技纵横》知网收录吗&#xff1f; 答&#xff1a;知网不收录&#xff0c;万方维普收录。主管单位&#xf…

leetcode及牛客网二叉树相关题、单值二叉树、相同的树、二叉树的前序、中序、后序遍历、另一棵树的子树、二叉树的遍历等的介绍

文章目录 前言一、单值二叉树二、相同的树三、二叉树的前序遍历四、二叉树的中序遍历五、二叉树的后序遍历六、另一棵树的子树七、二叉树的遍历总结 前言 leetcode及牛客网二叉树相关题、单值二叉树、相同的树、二叉树的前序、中序、后序遍历、另一棵树的子树、二叉树的遍历等…

21 厂商考证介绍(华为 华三 锐键 深信服)+AI 解析

一 认识考证体系 二 明确考证的大致方向 锐键 职业资格证书等级介绍 职业资格证书是由国家职业资格鉴定机构或相关行业主管部门颁发的&#xff0c;用于证明一个人在特定职业领域具备一定技能和知识水平的证明文件。职业资格证书的等级分为初级、中级、高级、技师、高级技师、…

一个HL7的模拟工具

这个模拟器是为了过&#xff08; NIST美国国家标准与技术研究院&#xff08;National Institute of Standards and Technology&#xff0c;NIST&#xff09;的电子病历住院部分的认证而写的。 用途说明 inpatient中的lab order信息通过该工具向实验室转发该信息。并将实验室…

算法(二)二分查找

文章目录 二分查找简介实现方式循环方式递归方式 经典例子 二分查找简介 二分查找&#xff08;binary search&#xff09;算法&#xff0c;也叫折半算法。二分查找是针对有序的数据集合的查找办法&#xff0c;如果是无序的数据结合就使用遍历。二分查找之所以快速&#xff0c;…

MATLAB的plot3使用技巧|更改视角|例程分享链接

plot3命令 MATLAB的plot3函数是用来绘制3D图形的函数。它可以将三维数据可视化为线段、点、曲线等形式。plot3函数可以用于绘制三维空间中的曲线、曲面、散点图等。 plot3函数的基本用法是&#xff1a; plot3(X,Y,Z)&#xff1a;绘制三维线段&#xff0c;其中X、Y、Z分别是包…

使用C#实现VS窗体应用——画图板

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。&#x1f34e;个人主页&#xff1a;Meteors.的博客&#x1f49e;当前专栏&#xff1a;小项目✨特色专栏&#xff1a; 知识分享&#x1f96d…

FinalShell无法连接Linux

Linux使用Vmware会创建一个网络&#xff0c;让两个子网处于一个网关&#xff0c;这样就能在windows中连接Linux&#xff0c;只有在这种情况下才能FinalShell才能连接Linux

Java过滤特殊空格nbsp;

现象&#xff1a; 用Java处理excel文件中的以下字符串时&#xff0c;想去除此空格&#xff0c;却发现用String.trim()没有直到预期效果&#xff1a; 原因&#xff1a; 在网上找了下&#xff0c;应该是这其实是html中经常使用的一种特殊空格字符&nbsp&#xff1b; 处理&a…

关于PyQt5的TreeWidget的与百度Ai的问答

中肯的讲啊&#xff0c;不带有任何色彩啊&#xff0c;百度Ai在编程这方面确实差了点。确实是在网罗所有资料&#xff0c;但是收集起来不能进行深度的分析&#xff0c;好像没有设置一个自己先把总结出的代码答案运行一下的功能&#xff0c;所以有时候给出的代码答案根本跑不了。…