华为

千呼万唤的华为,终于有开奖消息了。

从流出的薪资信息来看,AI 算法、芯片(海思)等核心技术岗位的薪酬挺有竞争力的,尤其是高级别(如 15 级)的 Offer。

华为的薪资结构通常为「月薪 * 12 + 年终奖」,其中年终奖部分可能与绩效挂钩,存在一定的浮动空间(不一定能拿满)。

华为开奖,不同部门、不同地区的进度会有所差异,有参与华为校招的小伙伴,最近记得密切留意 HR 消息,必要的时候可以给 HR 一些压力。

以下都是一些具体的开奖案例(数据来源:offershow):

  • 算法(上海):46k * 12,年终奖 35W,无签字费

  • AI 算法(深圳):46k * 12,年终奖 35W,无签字费

  • AI 算法(上海):15 级,总包 45W~50W,无签字费

  • 海思(上海):31k * 12,年终奖 10W,无签字费

虽然华为有些文化,总是被人议论,但对于某些地区来说,华为可能是唯一的大厂选择,所以我每年都建议大家投递,尤其目前校招(几乎)是唯一成为华为正式员工途径的情况下。

...

回归主题。

来一道和「华为(校招)」相关的算法题。

题目描述

平台:LeetCode

题号:1600

一个王国里住着国王、他的孩子们、他的孙子们等等。

每一个时间点,这个家庭里有人出生也有人死亡。

这个王国有一个明确规定的皇位继承顺序,第一继承人总是国王自己。我们定义递归函数 Successor(x, curOrder) ,给定一个人 x 和当前的继承顺序,该函数返回 x 的下一继承人。

Successor(x, curOrder):
    如果 x 没有孩子或者所有 x 的孩子都在 curOrder 中:
        如果 x 是国王,那么返回 null
        否则,返回 Successor(x 的父亲, curOrder)
    否则,返回 x 不在 curOrder 中最年长的孩子

比方说,假设王国由国王,他的孩子 AliceBobAliceBob 年长)和 Alice 的孩子 Jack 组成。

  1. 一开始, curOrder 为  ["king"]
  2. 调用  Successor(king, curOrder) ,返回 Alice,所以我们将 Alice 放入 curOrder 中,得到  ["king", "Alice"]
  3. 调用  Successor(Alice, curOrder) ,返回 Jack,所以我们将 Jack 放入  curOrder 中,得到  ["king", "Alice", "Jack"]
  4. 调用  Successor(Jack, curOrder) ,返回 Bob,所以我们将 Bob 放入  curOrder 中,得到  ["king", "Alice", "Jack", "Bob"]
  5. 调用  Successor(Bob, curOrder),返回  null。最终得到继承顺序为  ["king", "Alice", "Jack", "Bob"]

通过以上的函数,我们总是能得到一个唯一的继承顺序。

请你实现 ThroneInheritance 类:

  • ThroneInheritance(string kingName) 初始化一个  ThroneInheritance 类的对象。国王的名字作为构造函数的参数传入。
  • void birth(string parentName, string childName) 表示  parentName 新拥有了一个名为  childName 的孩子。
  • void death(string name) 表示名为  name 的人死亡。一个人的死亡不会影响  Successor 函数,也不会影响当前的继承顺序。你可以只将这个人标记为死亡状态。
  • string[] getInheritanceOrder() 返回除去死亡人员的当前继承顺序列表。

示例:

输入:
["ThroneInheritance""birth""birth""birth""birth""birth""birth""getInheritanceOrder""death""getInheritanceOrder"]
[["king"], ["king""andy"], ["king""bob"], ["king""catherine"], ["andy""matthew"], ["bob""alex"], ["bob""asha"], [null], ["bob"], [null]]

输出:
[null, null, null, null, null, null, null, ["king""andy""matthew""bob""alex""asha""catherine"], null, ["king""andy""matthew""alex""asha""catherine"]]

解释:
ThroneInheritance t= new ThroneInheritance("king"); // 继承顺序:king
t.birth("king""andy"); // 继承顺序:king > andy
t.birth("king""bob"); // 继承顺序:king > andy > bob
t.birth("king""catherine"); // 继承顺序:king > andy > bob > catherine
t.birth("andy""matthew"); // 继承顺序:king > andy > matthew > bob > catherine
t.birth("bob""alex"); // 继承顺序:king > andy > matthew > bob > alex > catherine
t.birth("bob""asha"); // 继承顺序:king > andy > matthew > bob > alex > asha > catherine
t.getInheritanceOrder(); // 返回 ["king""andy""matthew""bob""alex""asha""catherine"]
t.death("bob"); // 继承顺序:king > andy > matthew > bob(已经去世)> alex > asha > catherine
t.getInheritanceOrder(); // 返回 ["king""andy""matthew""alex""asha""catherine"]

提示:

  • kingNameparentName,  childName 和  name 仅包含小写英文字母。
  • 所有的参数  childName 和  kingName 互不相同。
  • 所有  death 函数中的死亡名字 name 要么是国王,要么是已经出生了的人员名字。
  • 每次调用 birth(parentName, childName) 时,测试用例都保证 parentName 对应的人员是活着的。
  • 最多调用   次 birth 和  death
  • 最多调用  次  getInheritanceOrder

单向链表 & 标记删除

根据题意,我们需要将「新儿子」插入到「父亲」的「最后一个儿子」的「儿子们」的后面(「注意这是个递归过程」);如果该「父亲」还没有任何儿子,则直接插到「父亲」后面。

因此,我们需要在节点 Node 中使用一个 last 记录该节点的「最后一个儿子」,同时因为删除的时候,我们无法在 的复杂度内更新 last 信息,所以只能使用「标记删除」的方式。

Java 代码:

class ThroneInheritance {
    class Node {
        String name;
        Node next;
        Node last; // 记录最后一个儿子
        boolean isDeleted = false;
        Node (String _name) {
            name = _name;
        }
    }
    Map<String, Node> map = new HashMap<>();
    Node head = new Node(""), tail = new Node("");
    public ThroneInheritance(String name) {
        Node root = new Node(name);
        root.next = tail;
        head.next = root;
        map.put(name, root);
    }
    
    public void birth(String pname, String cname) {
        Node node = new Node(cname);
        map.put(cname, node);
        Node p = map.get(pname);
        Node tmp = p;
        while (tmp.last != null) tmp = tmp.last;
        node.next = tmp.next;
        tmp.next = node;
        p.last = node;
    }
    
    public void death(String name) {
        Node node = map.get(name);
        node.isDeleted = true;
    }
    
    public List<String> getInheritanceOrder() {
        List<String> ans = new ArrayList<>();
        Node tmp = head.next;
        while (tmp.next != null) {
            if (!tmp.isDeleted) ans.add(tmp.name);
            tmp = tmp.next;
        }
        return ans;
    }
}

C++ 代码:

class ThroneInheritance {
public:
    class Node {
    public:
        string name;
        Node* next;
        Node* last;
        bool isDeleted;
        
        Node(string _name) : name(_name), next(nullptr), last(nullptr), isDeleted(false) {}
    };

    unordered_map<string, Node*> map;
    Node* head;
    Node* tail;

    ThroneInheritance(string kingName) {
        head = new Node("");
        tail = new Node("");
        Node* root = new Node(kingName);
        root->next = tail;
        head->next = root;
        map[kingName] = root;
    }
    
    void birth(string parentName, string childName) {
        Node* node = new Node(childName);
        map[childName] = node;
        Node* p = map[parentName];
        Node* tmp = p;
        while (tmp->last != nullptr) tmp = tmp->last;
        node->next = tmp->next;
        tmp->next = node;
        p->last = node;
    }
    
    void death(string name) {
        Node* node = map[name];
        node->isDeleted = true;
    }
    
    vector<stringgetInheritanceOrder() {
        vector<string> ans;
        Node* tmp = head->next;
        while (tmp->next != nullptr) {
            if (!tmp->isDeleted) {
                ans.push_back(tmp->name);
            }
            tmp = tmp->next;
        }
        return ans;
    }
};

Python 代码:

class ThroneInheritance:
    class Node:
        def __init__(self, name):
            self.name = name
            self.next = None
            self.last = None 
            self.is_deleted = False
    
    def __init__(self, kingName: str):
        self.map = {}
        self.head = self.Node("")
        self.tail = self.Node("")
        root = self.Node(kingName)
        root.next = self.tail
        self.head.next = root
        self.map[kingName] = root
    
    def birth(self, parentName: str, childName: str) -> None:
        node = self.Node(childName)
        self.map[childName] = node
        p = self.map[parentName]
        tmp = p
        while tmp.last is not None:
            tmp = tmp.last
        
        node.next = tmp.next
        tmp.next = node
        p.last = node
    
    def death(self, name: str) -> None:
        node = self.map[name]
        node.is_deleted = True
    
    def getInheritanceOrder(self) -> list:
        ans = []
        tmp = self.head.next
        while tmp.next is not None:
            if not tmp.is_deleted:
                ans.append(tmp.name)
            tmp = tmp.next
        return ans
  • 时间复杂度: birthgetInheritanceOrder 操作为 ;其余操作为
  • 时间复杂度:

最后

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

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

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

欢迎关注,明天见。

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

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐