2023-09-23力扣每日一题

链接:

1993. 树上的操作

题意

  • **Lock:**指定用户给指定节点 上锁 ,上锁后其他用户将无法给同一节点上锁。只有当节点处于未上锁的状态下,才能进行上锁操作。
  • **Unlock:**指定用户给指定节点 解锁 ,只有当指定节点当前正被指定用户锁住时,才能执行该解锁操作。
  • Upgrade:指定用户给指定节点 上锁 ,并且将该节点的所有子孙节点 解锁 。只有如下 3 个条件全部满足时才能执行升级操作:
    • 指定节点当前状态为未上锁。
    • 指定节点至少有一个上锁状态的子孙节点(可以是 任意 用户上锁的)。
    • 指定节点没有任何上锁的祖先节点。

基础的类设计,用到的是递归/dfs

可以用递归优化子节点的查询,同时把修改子节点的值

复制代码
 bool check2(int num)
    {
        bool ans=false;
        for(auto s:son[num])
        {
            ans |= book[s]!=0;
            book[s]=0;
            ans |= check2(s);
        }

        return ans;
    }

实际代码:

c++ 复制代码
class LockingTree {
public:
    vector<int>parent;
    vector<vector<int>>son;
    vector<int>book;
    LockingTree(vector<int>& parent) {
        this->parent=parent;
        book.resize(parent.size());
        son.resize(parent.size());
        
        for(int i=0;i<parent.size();i++)
        {
            if(parent[i]>=0)
            {
                son[parent[i]].push_back(i);
            }
        }
    }
    
    bool lock(int num, int user) {
        if(book[num]==0)
        {
            book[num]=user;
            return true;
        }

        return false;
    }
    
    bool unlock(int num, int user) {
        if(book[num]==user)
        {
            book[num]=0;
            return true;
        }

        return false;
    }
    
    bool upgrade(int num, int user) {
        if(book[num]==0)
        {
            if(check1(num) && check2(num))
            {
                book[num]=user;
                //clear(num);
                return true;
            }
        }

        return false;
    }

    bool check2(int num)
    {
        bool ans=false;
        vector<int>begin=son[num];
        while(true)
        {
            vector<int>next;
            for(auto b:begin)
            {
                if(book[b])
                {
                    ans=true;
                    book[b]=0;
                }
                for(auto bson:son[b])
                {
                    next.push_back(bson);
                }
            }
            if(next.empty()) break;
            begin=next;
        }

        return ans;
    }

    bool check1(int num)
    {
        while(parent[num]!=-1)
        {
            num=parent[num];
            if(book[num]) return false;
        }

        return true;
    }

    void clear(int num)
    {
        vector<int>begin=son[num];
        while(true)
        {
            vector<int>next;
            for(auto b:begin)
            {
                if(book[b]) book[b]=0;
                for(auto bson:son[b])
                {
                    next.push_back(bson);
                }
            }
            if(next.empty()) break;
            begin=next;
        }
    }
};

/**
 * Your LockingTree object will be instantiated and called as such:
 * LockingTree* obj = new LockingTree(parent);
 * bool param_1 = obj->lock(num,user);
 * bool param_2 = obj->unlock(num,user);
 * bool param_3 = obj->upgrade(num,user);
 */

限制:

  • n == parent.length
  • 2 <= n <= 2000
  • 对于 i != 0 ,满足 0 <= parent[i] <= n - 1
  • parent[0] == -1
  • 0 <= num <= n - 1
  • 1 <= user <= 104
  • parent 表示一棵合法的树。
  • lockunlockupgrade 的调用 总共 不超过 2000 次。
相关推荐
聚客AI7 小时前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v10 小时前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工12 小时前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农13 小时前
【React用到的一些算法】游标和栈
算法·react.js
博笙困了14 小时前
AcWing学习——双指针算法
c++·算法
moonlifesudo14 小时前
322:零钱兑换(三种方法)
算法
NAGNIP1 天前
大模型框架性能优化策略:延迟、吞吐量与成本权衡
算法
美团技术团队1 天前
LongCat-Flash:如何使用 SGLang 部署美团 Agentic 模型
人工智能·算法
Fanxt_Ja2 天前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
侃侃_天下2 天前
最终的信号类
开发语言·c++·算法