链接:
题意
- **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
表示一棵合法的树。lock
,unlock
和upgrade
的调用 总共 不超过2000
次。