说好的华为很卷呢?

华为"不卷"?

进入七八月份,大多数校招和实习都已尘埃落定。

也开始有不少新入职的同学入职"满月",开始在社交媒体上分享自己的工作感受。

最近牛客网上,一篇《说好的华为很卷的呢》引发了广泛争议,也让我们进一步了解到了华为实习生的现象:

alt

这位同学在帖子中分享道:进来之前以为是 996,结果一看其实是每周 40 小时工作制,每个月末周六再加一天班用于换年假。

部门弹性上班,最晚 9 点上班,最早 17:30 下班,中间 12:00 ~ 13:30 和 17:30 ~ 18:00 不算工时。

按照部门惯例,每周一二四晚点走,目的是领夜宵凑工时,周三周五则是朝九晚五。

而且据这位同学观察,这还只是明面上的规则,实际上中午休息时间多达 2.5 小时,晚上到 19:00 大家都还在摸鱼。

好家伙,不看评论区我还真的信了 🤣🤣🤣

不少评论区都指出了问题的关键:实习生岗位不能代表华为强度。

alt
alt
alt
alt

有些其他同为"实习生岗位"的同学,体验和楼主相差甚远。

在华为工作的节奏和网上说的没差,有些是因为对接海外,日夜颠倒,有些则是 9116 的作息,累的要死:

alt
alt

...

回归主题。

来一道和「快手」相关的算法题。

题目描述

平台:LeetCode

题号:558

二进制矩阵中的所有元素不是 0 就是 1 。

给你两个四叉树,quadTree1quadTree2

其中 quadTree1 表示一个 二进制矩阵,而 quadTree2 表示另一个 二进制矩阵。

请你返回一个表示 二进制矩阵的四叉树,它是 quadTree1quadTree2 所表示的两个二进制矩阵进行按位逻辑或运算的结果。

注意,当 isLeafFalse 时,你可以把 True 或者 False 赋值给节点,两种值都会被判题机制接受。

四叉树数据结构中,每个内部节点只有四个子节点。

此外,每个节点都有两个属性:

  • val:储存叶子结点所代表的区域的值。 对应 True, 对应 False
  • isLeaf: 当这个节点是一个叶子结点时为 True,如果它有 个子节点则为 False
class Node {
    public boolean val;
    public boolean isLeaf;
    public Node topLeft;
    public Node topRight;
    public Node bottomLeft;
    public Node bottomRight;
}

我们可以按以下步骤为二维区域构建四叉树:

  1. 如果当前网格的值相同(即全为 或者全为 ),将 isLeaf 设为 True ,将 val 设为网格相应的值,并将四个子节点都设为 Null 然后停止。
  2. 如果当前网格的值不同,将 isLeaf 设为 False, 将 val 设为任意值,然后如下图所示,将当前网格划分为四个子网格。
  3. 使用适当的子网格递归每个子节点。

四叉树格式:

输出为使用层序遍历后四叉树的序列化形式,其中 null 表示路径终止符,其下面不存在节点。

它与二叉树的序列化非常相似。唯一的区别是节点以列表形式表示 [isLeaf, val]

如果 isLeaf 或者 val 的值为 True,则表示它在列表 [isLeaf, val] 中的值为 1;如果 isLeaf 或者 val 的值为 False,则表示值为 0。

示例 1: alt

输入:quadTree1 = [[0,1],[1,1],[1,1],[1,0],[1,0]]
, quadTree2 = [[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]]

输出:[[0,0],[1,1],[1,1],[1,1],[1,0]]

解释:quadTree1 和 quadTree2 如上所示。由四叉树所表示的二进制矩阵也已经给出。
如果我们对这两个矩阵进行按位逻辑或运算,则可以得到下面的二进制矩阵,由一个作为结果的四叉树表示。
注意,我们展示的二进制矩阵仅仅是为了更好地说明题意,你无需构造二进制矩阵来获得结果四叉树。

示例 2:

输入:quadTree1 = [[1,0]]
, quadTree2 = [[1,0]]

输出:[[1,0]]

解释:两个数所表示的矩阵大小都为 1*1,值全为 0 
结果矩阵大小为 1*1,值全为 0 。

示例 3:

输入:quadTree1 = [[0,0],[1,0],[1,0],[1,1],[1,1]]
, quadTree2 = [[0,0],[1,1],[1,1],[1,0],[1,1]]

输出:[[1,1]]

示例 4:

输入:quadTree1 = [[0,0],[1,1],[1,0],[1,1],[1,1]]
, quadTree2 = [[0,0],[1,1],[0,1],[1,1],[1,1],null,null,null,null,[1,1],[1,0],[1,0],[1,1]]

输出:[[0,0],[1,1],[0,1],[1,1],[1,1],null,null,null,null,[1,1],[1,0],[1,0],[1,1]]

示例 5:

输入:quadTree1 = [[0,1],[1,0],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]]
, quadTree2 = [[0,1],[0,1],[1,0],[1,1],[1,0],[1,0],[1,0],[1,1],[1,1]]

输出:[[0,0],[0,1],[0,1],[1,1],[1,0],[1,0],[1,0],[1,1],[1,1],[1,0],[1,0],[1,1],[1,1]]

提示:

  • quadTree1quadTree2 都是符合题目要求的四叉树,每个都代表一个 的矩阵。
  • ,其中

递归

为了方便,我们令 quadTree1t1,令 quadTree2t2

根据题意,并利用给定函数作为递归函数,当 t1t2 均为叶子节点数时,执行「与逻辑」,即若 t1t2 任一值为 1 时,返回该节点,否则(两者均为 0),返回任一节点。

然后考虑其他情况下,如何使用 t1t2 构造新节点 ans,分别使用对应位置的进行「递归」构造即可(即使用 t1.topLeftt2.topLeft 来赋值给 ans.topLeft,其余位置同理),要注意可能存在 t1t2 其中一节点为叶子节点的情况,此时应当使用当前叶子节点和另一节点的子节点进行构造。

最后考虑什么情况下,会产生新的叶子节点:若当前节点 ans 的四个子节点均为叶子节点,并且值相同时,ans 会成为叶子节点,ans 值为叶子节点的值,此时需要执行的操作为将 isLeaf 设定为 True,修改 val 为原子节点的值,将四个原子节点置空。

Java 代码:

class Solution {
    public Node intersect(Node t1, Node t2) {
        if (t1.isLeaf && t2.isLeaf) {
            if (t1.val) return t1;
            else if (t2.val) return t2;
            else return t1;
        }
        Node ans = new Node();
        ans.topLeft = intersect(t1.isLeaf ? t1 : t1.topLeft, t2.isLeaf ? t2 : t2.topLeft);
        ans.topRight = intersect(t1.isLeaf ? t1 : t1.topRight, t2.isLeaf ? t2 : t2.topRight);
        ans.bottomLeft = intersect(t1.isLeaf ? t1 : t1.bottomLeft, t2.isLeaf ? t2 : t2.bottomLeft);
        ans.bottomRight = intersect(t1.isLeaf ? t1 : t1.bottomRight, t2.isLeaf ? t2 : t2.bottomRight);
        boolean a = ans.topLeft.isLeaf && ans.topRight.isLeaf && ans.bottomLeft.isLeaf && ans.bottomRight.isLeaf;
        boolean b = ans.topLeft.val && ans.topRight.val && ans.bottomLeft.val && ans.bottomRight.val;
        boolean c = ans.topLeft.val || ans.topRight.val || ans.bottomLeft.val || ans.bottomRight.val;
        ans.isLeaf = a && (b || !c);
        ans.val = ans.topLeft.val;
        if (ans.isLeaf) ans.topLeft = ans.topRight = ans.bottomLeft = ans.bottomRight = null;
        return ans;
    }
}

TypeScript 代码:

function intersect(t1: Node | null, t2: Node | null): Node | null {
    if (t1.isLeaf && t2.isLeaf) {
        if (t1.val) return t1
        else if (t2.val) return t2
        else return t1
    }
    const ans: Node = new Node()
    ans.topLeft = intersect(t1.isLeaf ? t1 : t1.topLeft, t2.isLeaf ? t2 : t2.topLeft)
    ans.topRight = intersect(t1.isLeaf ? t1 : t1.topRight, t2.isLeaf ? t2 : t2.topRight)
    ans.bottomLeft = intersect(t1.isLeaf ? t1 : t1.bottomLeft, t2.isLeaf ? t2 : t2.bottomLeft)
    ans.bottomRight = intersect(t1.isLeaf ? t1 : t1.bottomRight, t2.isLeaf ? t2 : t2.bottomRight)
    const a: boolean = ans.topLeft.isLeaf && ans.topRight.isLeaf && ans.bottomLeft.isLeaf && ans.bottomRight.isLeaf
    const b: boolean = ans.topLeft.val && ans.topRight.val && ans.bottomLeft.val && ans.bottomRight.val
    const c: boolean = ans.topLeft.val || ans.topRight.val || ans.bottomLeft.val || ans.bottomRight.val
    ans.isLeaf = a && (b || !c)
    ans.val = ans.topLeft.val
    if (ans.isLeaf) ans.topLeft = ans.topRight = ans.bottomLeft = ans.bottomRight = null
    return ans
};
  • 时间复杂度:复杂度与最终矩阵大小相关,而最终矩阵大小不会超过原矩阵大小,复杂度为
  • 空间复杂度:忽略递归带来的额外空间开销,复杂度为

最后

巨划算的 LeetCode 会员优惠通道目前仍可用 ~

使用福利优惠通道 leetcode.cn/premium/?promoChannel=acoier,年度会员 有效期额外增加两个月,季度会员 有效期额外增加两周,更有超大额专属 🧧 和实物 🎁 福利每月发放。

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

欢迎关注,明天见。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值