-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path024_locking_binary_tree.py
More file actions
63 lines (48 loc) · 1.87 KB
/
Copy path024_locking_binary_tree.py
File metadata and controls
63 lines (48 loc) · 1.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# Implement locking in a binary tree. A binary tree node can be locked or unlocked only if all of its descendants or ancestors are not locked.
# Design a binary tree node class with the following methods:
# is_locked, which returns whether the node is locked
# lock, which attempts to lock the node. If it cannot be locked, then it should return false. Otherwise, it should lock it and return true.
# unlock, which unlocks the node. If it cannot be unlocked, then it should return false. Otherwise, it should unlock it and return true.
class LockingBinaryTreeNode(object):
def __init__(self, val, left=None, right=None, parent=None):
self.val = val
self.left = left
self.right = right
self.parent = parent
self.locked = False
self.locked_descendants_count = 0
def _can_lock_or_unlock(self):
if self.locked_descendants_count > 0:
return False
cur = self.parent
while cur:
if cur.locked:
return False
cur = cur.parent
return True
def is_locked(self):
return self.locked
def lock(self):
if self.locked:
return False # node already locked
if not self._can_lock_or_unlock():
return False
# Not locked, so update locked and increment count in all ancestors
self.locked = True
cur = self.parent
while cur:
cur.locked_descendants_count += 1
cur = cur.parent
return True
def unlock(self):
if not self.locked:
return False # node already unlocked
if not self._can_lock_or_unlock():
return False
self.locked = False
# Update count in all ancestors
cur = self.parent
while cur:
cur.locked_descendants_count -= 1
cur = cur.parent
return True