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 次。
相关推荐
passer__jw7671 小时前
【LeetCode】【算法】3. 无重复字符的最长子串
算法·leetcode
passer__jw7671 小时前
【LeetCode】【算法】21. 合并两个有序链表
算法·leetcode·链表
sweetheart7-71 小时前
LeetCode22. 括号生成(2024冬季每日一题 2)
算法·深度优先·力扣·dfs·左右括号匹配
__AtYou__3 小时前
Golang | Leetcode Golang题解之第557题反转字符串中的单词III
leetcode·golang·题解
李元豪3 小时前
【智鹿空间】c++实现了一个简单的链表数据结构 MyList,其中包含基本的 Get 和 Modify 操作,
数据结构·c++·链表
2401_858286113 小时前
L7.【LeetCode笔记】相交链表
笔记·leetcode·链表
我不是星海3 小时前
1.集合体系补充(1)
java·数据结构
景鹤4 小时前
【算法】递归+回溯+剪枝:78.子集
算法·机器学习·剪枝
_OLi_4 小时前
力扣 LeetCode 704. 二分查找(Day1:数组)
算法·leetcode·职场和发展
丶Darling.5 小时前
Day40 | 动态规划 :完全背包应用 组合总和IV(类比爬楼梯)
c++·算法·动态规划·记忆化搜索·回溯