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 次。
相关推荐
爱吃生蚝的于勒1 分钟前
【Linux】零基础学会linux环境基础开发工具使用(yum,vim,makefile,gdb)
linux·服务器·数据结构·c++·蓝桥杯·编辑器·vim
熬了夜的程序员8 分钟前
【LeetCode】74. 搜索二维矩阵
线性代数·算法·leetcode·职场和发展·矩阵·深度优先·动态规划
蓝色汪洋8 分钟前
oj字符矩阵
算法
点云SLAM8 分钟前
矩阵奇异值分解算法(SVD)的导数 / 灵敏度分析
人工智能·线性代数·算法·机器学习·矩阵·数据压缩·svd算法
坚持编程的菜鸟9 分钟前
LeetCode每日一题——矩阵置0
c语言·算法·leetcode·矩阵
零基础的修炼15 分钟前
Linux---线程封装
linux·c++·算法
chao18984442 分钟前
基于MATLAB的双摆系统阻抗控制实现
算法
龙腾AI白云2 小时前
大模型-AIGC技术在文本生成与音频生成领域的应用
算法
坚持编程的菜鸟6 小时前
LeetCode每日一题——困于环中的机器人
c语言·算法·leetcode·机器人
Aurorar0rua7 小时前
C Primer Plus Notes 09
java·c语言·算法