如何解决经理同行问题?
How to solve manager peer problem question?
我在 google 采访中被问到以下问题但无法回答。我进行了 google 搜索,但找不到解决此问题的任何正确方法。你能帮我解决这个问题吗?
Design a data structure to support following functions:
- setManager(A, B) sets A as a direct manager of B
- setPeer(A, B) sets A as a colleague of B. After that, A and B will have the same direct Manager.
- query(A, B) returns if A is in the management chain of B.
Every person only has 1 direct manager.
让我们将每组同行视为代表公司管理链的层次结构树中的一个节点。我们知道它是一棵树,因为每个人只有 1 个直接经理。
我们将拥有以下形式的树:
快速想法:
setManager
只是连接 2 个节点(如果节点不存在,也会创建节点)。
setPeer
只是更新一个节点以包含另一个节点(如果节点已经存在);或为两个对等体创建一个节点(如果该节点的 none 存在);或合并 2 个现有节点(如果为每个对等体独立创建 2 个节点)。
query(A, B)
只是向上遍历树,检查该路径上的节点是否包含员工A。
- 一个额外的问题:给定一个员工 X,我们需要获得对相应节点的访问权限(可以通过额外的哈希 table 来解决,它从每个员工映射到他们对应的引用节点)。
上述思路的代码
public class EmployeeManagement {
private Dictionary < string, Node > _employeeToNode;
public EmployeeManagement() {
_employeeToNode = new Dictionary < string, Node > ();
}
public void SetManager(string manager, string employee) {
if (!_employeeToNode.ContainsKey(manager)) {
_employeeToNode[manager] = new Node(null, manager);
}
if (!_employeeToNode.ContainsKey(employee)) {
_employeeToNode[employee] = new Node(_employeeToNode[manager], employee);
} else {
_employeeToNode[employee].SetManagerNode(_employeeToNode[manager]);
}
}
public void SetPeer(string employeeA, string employeeB) {
if (_employeeToNode.ContainsKey(employeeA) && _employeeToNode.ContainsKey(employeeB)) {
if (_employeeToNode[employeeA].HasEmployee(employeeB) &&
_employeeToNode[employeeB].HasEmployee(employeeA)) {
return;
}
// Merge node of A and B if distinct
Node newNode = _employeeToNode[employeeA];
Node oldNode = _employeeToNode[employeeB];
if (_employeeToNode[employeeB].EmployeeCount() > newNode.EmployeeCount()) {
newNode = _employeeToNode[employeeB];
oldNode = _employeeToNode[employeeA];
}
if (!newNode.HasManager()) {
newNode.SetManagerNode(oldNode.GetManagerNode());
}
foreach(var employee in oldNode.GetEmployees()) {
newNode.AddEmployee(employee);
}
_employeeToNode[employeeA] = newNode;
_employeeToNode[employeeB] = newNode;
foreach(var employee in oldNode.GetEmployees()) {
_employeeToNode[employee] = newNode;
}
} else if (_employeeToNode.ContainsKey(employeeA)) {
_employeeToNode[employeeB] = _employeeToNode[employeeA];
} else if (_employeeToNode.ContainsKey(employeeB)) {
_employeeToNode[employeeA] = _employeeToNode[employeeB];
} else {
// Create a new node for both A and B
Node forAB = new Node(null, employeeA);
forAB.AddEmployee(employeeB);
_employeeToNode[employeeA] = forAB;
_employeeToNode[employeeB] = forAB;
}
}
/// <summary>
/// Check if A is in the management chain of B
/// </summary>
public bool Query(string employeeA, string employeeB) {
if (!_employeeToNode.ContainsKey(employeeA) || !_employeeToNode.ContainsKey(employeeB)) {
return false; // no info of employee A or employee B yet
}
Node managersOfB = _employeeToNode[employeeB].GetManagerNode();
while (managersOfB != null) {
if (managersOfB.HasEmployee(employeeA)) {
return true;
}
managersOfB = managersOfB.GetManagerNode();
}
return false; // not found A in the management chain of B
}
}
private class Node {
private Node _directManagers;
private HashSet < string > _employees;
public Node(Node directManagers, string employee) {
_directManagers = directManagers;
_employees = new HashSet < string > ();
_employees.Add(employee);
}
public bool HasManager() {
return _directManagers != null;
}
public void SetManagerNode(Node directManagers) {
_directManagers = directManagers;
}
public Node GetManagerNode() {
return _directManagers;
}
public void AddEmployee(string employee) {
_employees.Add(employee);
}
public HashSet < string > GetEmployees() {
return _employees;
}
public bool HasEmployee(string employee) {
return _employees.Contains(employee);
}
public int EmployeeCount() {
return _employees.Count;
}
}
假设您有以下人员class:
struct Person {
// we need to store the manager, obviously
Person* manager = nullptr;
// we also need to store the peers to assign the correct
// manager for all when it is set for one person in the group
shared_ptr<vector<Person*>> peerGroup = make_shared<vector<Person*>>({this});
};
一个人,当新创建的时候,没有经理和一个只包含这个人本身的对等组。
假设A、B等不是字符串而是Person*
,可以实现方法如下:
void setManager(Person* a, Person* b) {
for (Person* person : *b->peerGroup) person->manager = a;
}
void setPeer(Person* a, Person* b) {
// merge peer groups of a and b
// by first adding b's peers to a's peer group
// and then setting b's peer group to a's peer group
for (Person* person : *b->peerGroup) a->peerGroup->push_back(person);
b->peerGroup = a->peerGroup;
}
bool query(Person* a, Person* b) {
// we want to find out if a is managed by b
// so we go up the hierarchy, starting from a
Person* current = a;
while (current->manager != nullptr) {
// stop if b is (indirect) manager of a
if (current->manager == b) return true;
current = current->manager;
}
// we reached the top of the hierarchy and did not find b
return false;
}
如果您确实收到了字符串(如“A”、“B”、...),您可以使用散列映射来查看您是否已经为此名称创建了一个 Person
对象,如果没有创建一个:
map<string, unique_ptr<Person>> persons;
Person* getPerson(string name) {
if (!persons.contains(name)) {
persons[name] = make_unique<Person>();
}
return persons[name].get()
}
这可以通过单个 class、Employee
来完成,其中包含一个 attribute/member _manager
,它是对该员工经理的引用(如果有的话)和一个attribute/member '_managees',该员工管理的所有员工 instances/objects 的集合。
注意:我完全按照我对问题定义的解释,即要点 1-3,而不是 OP 或任何其他人的解释。 setPeer的描述是将A设置为B的同事,之后A和B将拥有同一个直属Manager。这样调用setPeer(A, B)时,就是设置A 的经理成为 B 的经理,除非 B 有经理,否则这没有任何意义。而且每个人都有一个经理,除了老板老板,而老板老板顾名思义是没有同行的。因此,也许 A 刚刚升职(或降级或只是横向调动到另一个部门)。这并不意味着 A 的每个前同事都获得了相同的晋升,现在也有相同的新经理。所以我认为这是一个 less-complicated 问题,而不是其他人所认为的问题。
class Employee:
def __init__(self, name, manager=None):
self._name = name
self._managees = set()
self._manager = None # so far
if manager:
self.set_manager(manager) # Could be none if this is the "top dog"
def __repr__(self):
return f'Name: {self._name}, Managed By: {self._manager._name if self._manager else ""}, Manages: {[managee._name for managee in self._managees]}'
def get_name(self):
return self._name
def get_manager(self):
return self._manager
def get_managees(self):
return self._managees
def manages(self, employee):
return employee in self._managees
def is_managed_by(self, employee):
return self._manager is employee
def remove_manager(self):
"""
We are no longer managed by anyone.
"""
if self._manager:
self._manager.remove_managee(self)
self._manager = None
return self
def remove_managee(self, managee):
"""
This manager no longer manages managee.
"""
self._managees.remove(managee)
managee._manager = None # No longer has a manager
return self
def set_manager(self, manager):
if not manager:
self.remove_manager()
return self
if self._manager:
# We have an existing manager:
self._manager.remove_managee(self)
self._manager = manager
manager._managees.add(self)
return self
def add_managee(self, managee):
"""
This manager now manages managee.
"""
managee.set_manager(self)
return sell
def set_peer(self, managee):
assert managee._manager # Make sure managee can have a peer
self.set_manager(managee._manager)
return self
@staticmethod
def query(employee1, employee2):
"""
Is employee1 in the management chain of employee2?
"""
manager = employee2._manager
while manager:
if manager is employee1:
return True
manager = manager._manager
return False
tom = Employee('Tom')
dick = Employee('Dick', tom)
harry = Employee('Harry', dick)
sally = Employee('Sally')
sally.set_manager(harry)
assert sally.is_managed_by(harry) and harry.manages(sally)
sally.set_manager(tom)
assert sally.is_managed_by(tom) and tom.manages(sally)
sally.set_peer(harry)
assert sally.is_managed_by(dick) and dick.manages(sally)
assert Employee.query(tom, harry)
assert not Employee.query(harry, dick)
print(tom)
print(dick)
print(harry)
print(sally)
打印:
Name: Tom, Managed By: , Manages: ['Dick']
Name: Dick, Managed By: Tom, Manages: ['Harry', 'Sally']
Name: Harry, Managed By: Dick, Manages: []
Name: Sally, Managed By: Dick, Manages: []
使用三个散列 tables 1. 员工到组 ID 映射 (emp) 2. 组 ID 到员工列表 (gid) 3. 组 ID -> 经理 ID table(经理)
int id = 0;
void setpeer(string A, string B) {
int id1 = 0;
int id2 = 0;
if (emp.find(A) != emp.end())
id1 = emp[A];
if (emp.find(B) != emp.end())
id2 = emp[B];
if (!id1 && !id2) {
++id;
emp[A] = id;
emp[B} = id;
gid[id].push_back(A);
gid[id].push_back(B);
} else if (!id1) {
emp[A] = id2;
gid[id2].push_back(A);
} else if (!id2) {
emp[B] = id1;
gid[id1].push_back(B);
} else {
for(i = 0;i<gid[id2].size();i++) {
emp[gid[id2][i]] = id1;
gid[id1].push_back( gid[id2][i] );
}
if (manager.find(id2) != manager.end())
manager[id1] = manager[id2].
manager.erase(id2);
gid.erase(id2);
}
void setManager(string A, string B) {
int id1, id2;
if (emp.find(A) != emp.end())
id1 = emp[A];
else {
++id;
emp[A] = id;
id1 = id;
gid[id].push_back(A);
}
if (emp.find(B) != emp.end())
id2 = emp[B];
else {
++id;
emp[B] = id;
id2 = id;
gid[id].push_back(B);
}
manager[id2] = id1;
}
bool query(string A, string B) {
int id1 = 0, id2 = 0;
if (emp.find(A) != emp.end())
id1 = emp[A];
if (emp.find(B) != emp.end())
id2 = emp[B];
if (!id1 || !id2) //one of them does not exist
return false;
id2 = manager[id2];
while(id2 != 0) {
if (id2 == id1)
return true;
id2 = manager[id2];
}
return false;
}
int id = 0;
void setpeer(string A, string B) {
int id1 = 0;
int id2 = 0;
if (emp.find(A) != emp.end())
id1 = emp[A];
if (emp.find(B) != emp.end())
id2 = emp[B];
if (!id1 && !id2) {
++id;
emp[A] = id;
emp[B} = id;
gid[id].push_back(A);
gid[id].push_back(B);
} else if (!id1) {
emp[A] = id2;
gid[id2].push_back(A);
} else if (!id2) {
emp[B] = id1;
gid[id1].push_back(B);
} else {
for(i = 0;i<gid[id2].size();i++) {
emp[gid[id2][i]] = id1;
gid[id1].push_back( gid[id2][i] );
}
if (manager.find(id2) != manager.end())
manager[id1] = manager[id2].
manager.erase(id2);
gid.erase(id2);
}
void setManager(string A, string B) {
int id1, id2;
if (emp.find(A) != emp.end())
id1 = emp[A];
else {
++id;
emp[A] = id;
id1 = id;
gid[id].push_back(A);
}
if (emp.find(B) != emp.end())
id2 = emp[B];
else {
++id;
emp[B] = id;
id2 = id;
gid[id].push_back(B);
}
manager[id2] = id1;
}
bool query(string A, string B) {
int id1 = 0, id2 = 0;
if (emp.find(A) != emp.end())
id1 = emp[A];
if (emp.find(B) != emp.end())
id2 = emp[B];
if (!id1 || !id2) //one of them does not exist
return false;
id2 = manager[id2];
while(id2 != 0) {
if (id2 == id1)
return true;
id2 = manager[id2];
}
return false;
}
我在 google 采访中被问到以下问题但无法回答。我进行了 google 搜索,但找不到解决此问题的任何正确方法。你能帮我解决这个问题吗?
Design a data structure to support following functions:
- setManager(A, B) sets A as a direct manager of B
- setPeer(A, B) sets A as a colleague of B. After that, A and B will have the same direct Manager.
- query(A, B) returns if A is in the management chain of B. Every person only has 1 direct manager.
让我们将每组同行视为代表公司管理链的层次结构树中的一个节点。我们知道它是一棵树,因为每个人只有 1 个直接经理。
我们将拥有以下形式的树:
快速想法:
setManager
只是连接 2 个节点(如果节点不存在,也会创建节点)。setPeer
只是更新一个节点以包含另一个节点(如果节点已经存在);或为两个对等体创建一个节点(如果该节点的 none 存在);或合并 2 个现有节点(如果为每个对等体独立创建 2 个节点)。query(A, B)
只是向上遍历树,检查该路径上的节点是否包含员工A。- 一个额外的问题:给定一个员工 X,我们需要获得对相应节点的访问权限(可以通过额外的哈希 table 来解决,它从每个员工映射到他们对应的引用节点)。
上述思路的代码
public class EmployeeManagement {
private Dictionary < string, Node > _employeeToNode;
public EmployeeManagement() {
_employeeToNode = new Dictionary < string, Node > ();
}
public void SetManager(string manager, string employee) {
if (!_employeeToNode.ContainsKey(manager)) {
_employeeToNode[manager] = new Node(null, manager);
}
if (!_employeeToNode.ContainsKey(employee)) {
_employeeToNode[employee] = new Node(_employeeToNode[manager], employee);
} else {
_employeeToNode[employee].SetManagerNode(_employeeToNode[manager]);
}
}
public void SetPeer(string employeeA, string employeeB) {
if (_employeeToNode.ContainsKey(employeeA) && _employeeToNode.ContainsKey(employeeB)) {
if (_employeeToNode[employeeA].HasEmployee(employeeB) &&
_employeeToNode[employeeB].HasEmployee(employeeA)) {
return;
}
// Merge node of A and B if distinct
Node newNode = _employeeToNode[employeeA];
Node oldNode = _employeeToNode[employeeB];
if (_employeeToNode[employeeB].EmployeeCount() > newNode.EmployeeCount()) {
newNode = _employeeToNode[employeeB];
oldNode = _employeeToNode[employeeA];
}
if (!newNode.HasManager()) {
newNode.SetManagerNode(oldNode.GetManagerNode());
}
foreach(var employee in oldNode.GetEmployees()) {
newNode.AddEmployee(employee);
}
_employeeToNode[employeeA] = newNode;
_employeeToNode[employeeB] = newNode;
foreach(var employee in oldNode.GetEmployees()) {
_employeeToNode[employee] = newNode;
}
} else if (_employeeToNode.ContainsKey(employeeA)) {
_employeeToNode[employeeB] = _employeeToNode[employeeA];
} else if (_employeeToNode.ContainsKey(employeeB)) {
_employeeToNode[employeeA] = _employeeToNode[employeeB];
} else {
// Create a new node for both A and B
Node forAB = new Node(null, employeeA);
forAB.AddEmployee(employeeB);
_employeeToNode[employeeA] = forAB;
_employeeToNode[employeeB] = forAB;
}
}
/// <summary>
/// Check if A is in the management chain of B
/// </summary>
public bool Query(string employeeA, string employeeB) {
if (!_employeeToNode.ContainsKey(employeeA) || !_employeeToNode.ContainsKey(employeeB)) {
return false; // no info of employee A or employee B yet
}
Node managersOfB = _employeeToNode[employeeB].GetManagerNode();
while (managersOfB != null) {
if (managersOfB.HasEmployee(employeeA)) {
return true;
}
managersOfB = managersOfB.GetManagerNode();
}
return false; // not found A in the management chain of B
}
}
private class Node {
private Node _directManagers;
private HashSet < string > _employees;
public Node(Node directManagers, string employee) {
_directManagers = directManagers;
_employees = new HashSet < string > ();
_employees.Add(employee);
}
public bool HasManager() {
return _directManagers != null;
}
public void SetManagerNode(Node directManagers) {
_directManagers = directManagers;
}
public Node GetManagerNode() {
return _directManagers;
}
public void AddEmployee(string employee) {
_employees.Add(employee);
}
public HashSet < string > GetEmployees() {
return _employees;
}
public bool HasEmployee(string employee) {
return _employees.Contains(employee);
}
public int EmployeeCount() {
return _employees.Count;
}
}
假设您有以下人员class:
struct Person {
// we need to store the manager, obviously
Person* manager = nullptr;
// we also need to store the peers to assign the correct
// manager for all when it is set for one person in the group
shared_ptr<vector<Person*>> peerGroup = make_shared<vector<Person*>>({this});
};
一个人,当新创建的时候,没有经理和一个只包含这个人本身的对等组。
假设A、B等不是字符串而是Person*
,可以实现方法如下:
void setManager(Person* a, Person* b) {
for (Person* person : *b->peerGroup) person->manager = a;
}
void setPeer(Person* a, Person* b) {
// merge peer groups of a and b
// by first adding b's peers to a's peer group
// and then setting b's peer group to a's peer group
for (Person* person : *b->peerGroup) a->peerGroup->push_back(person);
b->peerGroup = a->peerGroup;
}
bool query(Person* a, Person* b) {
// we want to find out if a is managed by b
// so we go up the hierarchy, starting from a
Person* current = a;
while (current->manager != nullptr) {
// stop if b is (indirect) manager of a
if (current->manager == b) return true;
current = current->manager;
}
// we reached the top of the hierarchy and did not find b
return false;
}
如果您确实收到了字符串(如“A”、“B”、...),您可以使用散列映射来查看您是否已经为此名称创建了一个 Person
对象,如果没有创建一个:
map<string, unique_ptr<Person>> persons;
Person* getPerson(string name) {
if (!persons.contains(name)) {
persons[name] = make_unique<Person>();
}
return persons[name].get()
}
这可以通过单个 class、Employee
来完成,其中包含一个 attribute/member _manager
,它是对该员工经理的引用(如果有的话)和一个attribute/member '_managees',该员工管理的所有员工 instances/objects 的集合。
注意:我完全按照我对问题定义的解释,即要点 1-3,而不是 OP 或任何其他人的解释。 setPeer的描述是将A设置为B的同事,之后A和B将拥有同一个直属Manager。这样调用setPeer(A, B)时,就是设置A 的经理成为 B 的经理,除非 B 有经理,否则这没有任何意义。而且每个人都有一个经理,除了老板老板,而老板老板顾名思义是没有同行的。因此,也许 A 刚刚升职(或降级或只是横向调动到另一个部门)。这并不意味着 A 的每个前同事都获得了相同的晋升,现在也有相同的新经理。所以我认为这是一个 less-complicated 问题,而不是其他人所认为的问题。
class Employee:
def __init__(self, name, manager=None):
self._name = name
self._managees = set()
self._manager = None # so far
if manager:
self.set_manager(manager) # Could be none if this is the "top dog"
def __repr__(self):
return f'Name: {self._name}, Managed By: {self._manager._name if self._manager else ""}, Manages: {[managee._name for managee in self._managees]}'
def get_name(self):
return self._name
def get_manager(self):
return self._manager
def get_managees(self):
return self._managees
def manages(self, employee):
return employee in self._managees
def is_managed_by(self, employee):
return self._manager is employee
def remove_manager(self):
"""
We are no longer managed by anyone.
"""
if self._manager:
self._manager.remove_managee(self)
self._manager = None
return self
def remove_managee(self, managee):
"""
This manager no longer manages managee.
"""
self._managees.remove(managee)
managee._manager = None # No longer has a manager
return self
def set_manager(self, manager):
if not manager:
self.remove_manager()
return self
if self._manager:
# We have an existing manager:
self._manager.remove_managee(self)
self._manager = manager
manager._managees.add(self)
return self
def add_managee(self, managee):
"""
This manager now manages managee.
"""
managee.set_manager(self)
return sell
def set_peer(self, managee):
assert managee._manager # Make sure managee can have a peer
self.set_manager(managee._manager)
return self
@staticmethod
def query(employee1, employee2):
"""
Is employee1 in the management chain of employee2?
"""
manager = employee2._manager
while manager:
if manager is employee1:
return True
manager = manager._manager
return False
tom = Employee('Tom')
dick = Employee('Dick', tom)
harry = Employee('Harry', dick)
sally = Employee('Sally')
sally.set_manager(harry)
assert sally.is_managed_by(harry) and harry.manages(sally)
sally.set_manager(tom)
assert sally.is_managed_by(tom) and tom.manages(sally)
sally.set_peer(harry)
assert sally.is_managed_by(dick) and dick.manages(sally)
assert Employee.query(tom, harry)
assert not Employee.query(harry, dick)
print(tom)
print(dick)
print(harry)
print(sally)
打印:
Name: Tom, Managed By: , Manages: ['Dick']
Name: Dick, Managed By: Tom, Manages: ['Harry', 'Sally']
Name: Harry, Managed By: Dick, Manages: []
Name: Sally, Managed By: Dick, Manages: []
使用三个散列 tables 1. 员工到组 ID 映射 (emp) 2. 组 ID 到员工列表 (gid) 3. 组 ID -> 经理 ID table(经理)
int id = 0;
void setpeer(string A, string B) {
int id1 = 0;
int id2 = 0;
if (emp.find(A) != emp.end())
id1 = emp[A];
if (emp.find(B) != emp.end())
id2 = emp[B];
if (!id1 && !id2) {
++id;
emp[A] = id;
emp[B} = id;
gid[id].push_back(A);
gid[id].push_back(B);
} else if (!id1) {
emp[A] = id2;
gid[id2].push_back(A);
} else if (!id2) {
emp[B] = id1;
gid[id1].push_back(B);
} else {
for(i = 0;i<gid[id2].size();i++) {
emp[gid[id2][i]] = id1;
gid[id1].push_back( gid[id2][i] );
}
if (manager.find(id2) != manager.end())
manager[id1] = manager[id2].
manager.erase(id2);
gid.erase(id2);
}
void setManager(string A, string B) {
int id1, id2;
if (emp.find(A) != emp.end())
id1 = emp[A];
else {
++id;
emp[A] = id;
id1 = id;
gid[id].push_back(A);
}
if (emp.find(B) != emp.end())
id2 = emp[B];
else {
++id;
emp[B] = id;
id2 = id;
gid[id].push_back(B);
}
manager[id2] = id1;
}
bool query(string A, string B) {
int id1 = 0, id2 = 0;
if (emp.find(A) != emp.end())
id1 = emp[A];
if (emp.find(B) != emp.end())
id2 = emp[B];
if (!id1 || !id2) //one of them does not exist
return false;
id2 = manager[id2];
while(id2 != 0) {
if (id2 == id1)
return true;
id2 = manager[id2];
}
return false;
}
int id = 0;
void setpeer(string A, string B) {
int id1 = 0;
int id2 = 0;
if (emp.find(A) != emp.end())
id1 = emp[A];
if (emp.find(B) != emp.end())
id2 = emp[B];
if (!id1 && !id2) {
++id;
emp[A] = id;
emp[B} = id;
gid[id].push_back(A);
gid[id].push_back(B);
} else if (!id1) {
emp[A] = id2;
gid[id2].push_back(A);
} else if (!id2) {
emp[B] = id1;
gid[id1].push_back(B);
} else {
for(i = 0;i<gid[id2].size();i++) {
emp[gid[id2][i]] = id1;
gid[id1].push_back( gid[id2][i] );
}
if (manager.find(id2) != manager.end())
manager[id1] = manager[id2].
manager.erase(id2);
gid.erase(id2);
}
void setManager(string A, string B) {
int id1, id2;
if (emp.find(A) != emp.end())
id1 = emp[A];
else {
++id;
emp[A] = id;
id1 = id;
gid[id].push_back(A);
}
if (emp.find(B) != emp.end())
id2 = emp[B];
else {
++id;
emp[B] = id;
id2 = id;
gid[id].push_back(B);
}
manager[id2] = id1;
}
bool query(string A, string B) {
int id1 = 0, id2 = 0;
if (emp.find(A) != emp.end())
id1 = emp[A];
if (emp.find(B) != emp.end())
id2 = emp[B];
if (!id1 || !id2) //one of them does not exist
return false;
id2 = manager[id2];
while(id2 != 0) {
if (id2 == id1)
return true;
id2 = manager[id2];
}
return false;
}