Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Longest Consecutive Sequence Algorithm #81

Closed
wants to merge 8 commits into from
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ Click on the icons to search by language
- [ ] [path_sum](tree/binary_tree/path_sum)
- [ ] [serialize_deserialize](tree/binary_tree/serialize_deserialize)
- [ ] [traversal](tree/traversal)
- [ ] [inorder](tree/traversal/inorder)
- [x] [inorder](tree/traversal/inorder)
- [ ] [level_order](tree/traversal/level_order)
- [ ] [zigzag](tree/traversal/zigzag)
- [ ] [binary_search_tree](tree/binary_search_tree)
Expand All @@ -305,6 +305,8 @@ Click on the icons to search by language
- [ ] [trie](tree/trie)
- [ ] [add_and_search](tree/trie/add_and_search)
- [ ] [trie](tree/trie/trie)
- [x] [new_tree_algorithm](tree/new_tree_algorithm)
- [x] [boundary_traversal](tree/new_tree_algorithm/new_tree_algorithm)

- [x] [union-find](union-find)
- [x] [count_islands](union-find/count_islands.py)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
maxlen = 0


class Node:
def __init__(self, val=None):
self.left = None
Expand All @@ -15,21 +12,22 @@ def longest_consecutive(root):
"""
if not root:
return 0
DFS(root, 0, root.val)
return maxlen
return DFS(root, None, 0)


def DFS(root, cur, target):
global maxlen
def DFS(root, parent, length):
if not root:
return
if root.val == target:
cur += 1
return length

if parent and root.val == parent.val + 1:
length += 1
else:
cur = 1
maxlen = max(cur, maxlen)
DFS(root.left, cur, root.val + 1)
DFS(root.right, cur, root.val + 1)
length = 1

left_length = DFS(root.left, root, length)
right_length = DFS(root.right, root, length)

return max(length, left_length, right_length)


if __name__ == '__main__':
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import unittest
from longest_consecutive_sequence import Node, longest_consecutive

class TestLongestConsecutiveSequence(unittest.TestCase):
def test_example_case(self):
root = Node(1)
root.right = Node(3)
root.right.left = Node(2)
root.right.right = Node(4)
root.right.right.right = Node(5)
self.assertEqual(longest_consecutive(root), 3)

def test_empty_tree(self):
self.assertEqual(longest_consecutive(None), 0)

def test_single_node(self):
root = Node(1)
self.assertEqual(longest_consecutive(root), 1)

def test_no_consecutive_sequence(self):
root = Node(1)
root.left = Node(3)
root.right = Node(5)
self.assertEqual(longest_consecutive(root), 1)

def test_multiple_consecutive_sequences(self):
root = Node(1)
root.left = Node(2)
root.left.left = Node(3)
root.right = Node(4)
root.right.right = Node(5)
root.right.right.right = Node(6)
self.assertEqual(longest_consecutive(root), 3)

if __name__ == '__main__':
unittest.main()
61 changes: 61 additions & 0 deletions tree/binary_tree/novel_tree_algorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right

def find_deepest_leaf(root):
"""
Finds the deepest leaf node in a binary tree.

:param root: TreeNode, the root of the binary tree
:return: tuple (TreeNode, int), the deepest leaf node and its depth
"""
if not root:
return None, 0

def dfs(node, depth):
if not node.left and not node.right:
return node, depth

left_node, left_depth = dfs(node.left, depth + 1) if node.left else (None, depth)
right_node, right_depth = dfs(node.right, depth + 1) if node.right else (None, depth)

if left_depth >= right_depth:
return left_node, left_depth
else:
return right_node, right_depth

return dfs(root, 0)

# Example usage and test
if __name__ == "__main__":
# Create a sample binary tree
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.right.right = TreeNode(5)
root.right.right.left = TreeNode(6)

deepest_node, depth = find_deepest_leaf(root)
print(f"The deepest leaf node value is {deepest_node.val} at depth {depth}")

# Additional test cases
# Test case 1: Empty tree
assert find_deepest_leaf(None) == (None, 0)

# Test case 2: Tree with only root
assert find_deepest_leaf(TreeNode(1)) == (TreeNode(1), 0)

# Test case 3: Balanced tree
balanced_root = TreeNode(1)
balanced_root.left = TreeNode(2)
balanced_root.right = TreeNode(3)
balanced_root.left.left = TreeNode(4)
balanced_root.left.right = TreeNode(5)
balanced_root.right.left = TreeNode(6)
balanced_root.right.right = TreeNode(7)
assert find_deepest_leaf(balanced_root)[1] == 2

print("All test cases passed!")
56 changes: 56 additions & 0 deletions tree/binary_tree/test_novel_tree_algorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import unittest
from .novel_tree_algorithm import TreeNode, find_deepest_leaf

class TestNovelTreeAlgorithm(unittest.TestCase):
def test_empty_tree(self):
self.assertEqual(find_deepest_leaf(None), (None, 0))

def test_single_node_tree(self):
root = TreeNode(1)
node, depth = find_deepest_leaf(root)
self.assertEqual(node.val, 1)
self.assertEqual(depth, 0)

def test_balanced_tree(self):
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.left = TreeNode(6)
root.right.right = TreeNode(7)
node, depth = find_deepest_leaf(root)
self.assertIn(node.val, [4, 5, 6, 7])
self.assertEqual(depth, 2)

def test_unbalanced_tree(self):
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.right.right = TreeNode(5)
root.right.right.left = TreeNode(6)
node, depth = find_deepest_leaf(root)
self.assertEqual(node.val, 6)
self.assertEqual(depth, 3)

def test_left_heavy_tree(self):
root = TreeNode(1)
root.left = TreeNode(2)
root.left.left = TreeNode(3)
root.left.left.left = TreeNode(4)
node, depth = find_deepest_leaf(root)
self.assertEqual(node.val, 4)
self.assertEqual(depth, 3)

def test_right_heavy_tree(self):
root = TreeNode(1)
root.right = TreeNode(2)
root.right.right = TreeNode(3)
root.right.right.right = TreeNode(4)
node, depth = find_deepest_leaf(root)
self.assertEqual(node.val, 4)
self.assertEqual(depth, 3)

if __name__ == '__main__':
unittest.main()
71 changes: 71 additions & 0 deletions tree/new_tree_algorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class TreeNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None

class BinaryTree:
def __init__(self):
self.root = None

def insert(self, value):
if not self.root:
self.root = TreeNode(value)
else:
self._insert_recursive(self.root, value)

def _insert_recursive(self, node, value):
if value < node.value:
if node.left is None:
node.left = TreeNode(value)
else:
self._insert_recursive(node.left, value)
else:
if node.right is None:
node.right = TreeNode(value)
else:
self._insert_recursive(node.right, value)

def inorder_traversal(self):
result = []
self._inorder_recursive(self.root, result)
return result

def _inorder_recursive(self, node, result):
if node:
self._inorder_recursive(node.left, result)
result.append(node.value)
self._inorder_recursive(node.right, result)

def preorder_traversal(self):
result = []
self._preorder_recursive(self.root, result)
return result

def _preorder_recursive(self, node, result):
if node:
result.append(node.value)
self._preorder_recursive(node.left, result)
self._preorder_recursive(node.right, result)

def postorder_traversal(self):
result = []
self._postorder_recursive(self.root, result)
return result

def _postorder_recursive(self, node, result):
if node:
self._postorder_recursive(node.left, result)
self._postorder_recursive(node.right, result)
result.append(node.value)

# Example usage
if __name__ == "__main__":
tree = BinaryTree()
values = [5, 3, 7, 1, 4, 6, 8]
for value in values:
tree.insert(value)

print("Inorder traversal:", tree.inorder_traversal())
print("Preorder traversal:", tree.preorder_traversal())
print("Postorder traversal:", tree.postorder_traversal())
71 changes: 71 additions & 0 deletions tree/new_tree_algorithm/new_tree_algorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right

def is_leaf(node):
return node and not node.left and not node.right

def add_left_boundary(root, result):
current = root.left
while current:
if not is_leaf(current):
result.append(current.val)
if current.left:
current = current.left
else:
current = current.right

def add_leaves(root, result):
if is_leaf(root):
result.append(root.val)
else:
if root.left:
add_leaves(root.left, result)
if root.right:
add_leaves(root.right, result)

def add_right_boundary(root, result):
current = root.right
temp = []
while current:
if not is_leaf(current):
temp.append(current.val)
if current.right:
current = current.right
else:
current = current.left
result.extend(temp[::-1])

def boundary_traversal(root):
result = []
if not root:
return result

if not is_leaf(root):
result.append(root.val)

add_left_boundary(root, result)
add_leaves(root, result)
add_right_boundary(root, result)

return result

# Example usage
if __name__ == "__main__":
# Create a sample binary tree
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.left = TreeNode(6)
root.right.right = TreeNode(7)
root.left.left.left = TreeNode(8)
root.left.left.right = TreeNode(9)
root.right.right.left = TreeNode(10)
root.right.right.right = TreeNode(11)

# Perform boundary traversal
print("Boundary traversal:", boundary_traversal(root))
Loading
Loading