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 次。
相关推荐
Hello.Reader3 小时前
算法基础(十)——分治思想把大问题拆成小问题
java·开发语言·算法
绛橘色的日落(。・∀・)ノ3 小时前
机器学习之评估与偏差方差分析
算法
消失的旧时光-19433 小时前
C语言对象模型系列(四)《Linux 内核里的 container_of 到底是什么黑魔法?》—— 一篇讲透 Linux 内核的“对象模型”核心技巧
linux·c语言·算法
AI_Ming4 小时前
从0开始学AI:层归一化,原来是这回事!
算法·ai编程
WL_Aurora4 小时前
备战蓝桥杯国赛【Day 8】
算法·蓝桥杯
智者知已应修善业5 小时前
【51单片机模拟生日蜡烛】2023-10-10
c++·经验分享·笔记·算法·51单片机
MediaTea5 小时前
Scikit-learn:从数据到结构——无监督学习的最小闭环
人工智能·学习·算法·机器学习·scikit-learn
智者知已应修善业5 小时前
【51单片机如何让LED灯从一亮到八,再从八亮到一】2023-10-13
c++·经验分享·笔记·算法·51单片机
qeen875 小时前
【数据结构】二叉树相关经典函数C语言实现
c语言·数据结构·c++·笔记·学习·算法·二叉树
良木生香5 小时前
【C++初阶】STL——List从入门到应用完全指南(1)
开发语言·数据结构·c++·程序人生·算法·蓝桥杯·学习方法