-
Notifications
You must be signed in to change notification settings - Fork 138
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Resolve merge conflict in new_tree_algorithm.py
- Loading branch information
Showing
8 changed files
with
311 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
tree/binary_tree/longest_consecutive_sequence/test_longest_consecutive_sequence.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class TreeNode: | ||
def __init__(self, val=0, left=None, right=None): | ||
self.val = val | ||
self.left = left | ||
self.right = right | ||
|
||
def inorder_traversal(root): | ||
result = [] | ||
if root: | ||
result.extend(inorder_traversal(root.left)) | ||
result.append(root.val) | ||
result.extend(inorder_traversal(root.right)) | ||
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) | ||
|
||
# Perform inorder traversal | ||
print("Inorder traversal:", inorder_traversal(root)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
""" | ||
Implement a new Trie data structure with insert, search, and starts_with methods. | ||
This implementation uses a TrieNode class to represent each node in the Trie. | ||
Each TrieNode contains a dictionary of children nodes and a flag to indicate | ||
if it represents the end of a word. | ||
Note: | ||
- All inputs are assumed to consist of lowercase letters a-z. | ||
- This implementation aims to be more memory-efficient by using a regular | ||
dictionary instead of defaultdict for children nodes. | ||
""" | ||
|
||
|
||
class TrieNode: | ||
def __init__(self): | ||
self.children = {} | ||
self.is_end_of_word = False | ||
|
||
|
||
class Trie: | ||
def __init__(self): | ||
self.root = TrieNode() | ||
|
||
def insert(self, word: str) -> None: | ||
""" | ||
Inserts a word into the trie. | ||
Args: | ||
word (str): The word to be inserted. | ||
""" | ||
node = self.root | ||
for char in word: | ||
if char not in node.children: | ||
node.children[char] = TrieNode() | ||
node = node.children[char] | ||
node.is_end_of_word = True | ||
|
||
def search(self, word: str) -> bool: | ||
""" | ||
Returns True if the word is in the trie, False otherwise. | ||
Args: | ||
word (str): The word to search for. | ||
Returns: | ||
bool: True if the word is found, False otherwise. | ||
""" | ||
node = self._find_node(word) | ||
return node is not None and node.is_end_of_word | ||
|
||
def starts_with(self, prefix: str) -> bool: | ||
""" | ||
Returns True if there is any word in the trie that starts with the given prefix. | ||
Args: | ||
prefix (str): The prefix to search for. | ||
Returns: | ||
bool: True if any word starts with the given prefix, False otherwise. | ||
""" | ||
return self._find_node(prefix) is not None | ||
|
||
def _find_node(self, prefix: str) -> TrieNode: | ||
""" | ||
Helper method to find the node corresponding to the given prefix. | ||
Args: | ||
prefix (str): The prefix to search for. | ||
Returns: | ||
TrieNode: The node corresponding to the last character of the prefix, | ||
or None if the prefix is not found. | ||
""" | ||
node = self.root | ||
for char in prefix: | ||
if char not in node.children: | ||
return None | ||
node = node.children[char] | ||
return node |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import unittest | ||
from new_trie import Trie | ||
|
||
class TestTrie(unittest.TestCase): | ||
def setUp(self): | ||
self.trie = Trie() | ||
|
||
def test_insert_and_search(self): | ||
self.trie.insert("apple") | ||
self.assertTrue(self.trie.search("apple")) | ||
self.assertFalse(self.trie.search("app")) | ||
self.assertFalse(self.trie.search("apples")) | ||
|
||
def test_starts_with(self): | ||
self.trie.insert("apple") | ||
self.assertTrue(self.trie.starts_with("app")) | ||
self.assertTrue(self.trie.starts_with("apple")) | ||
self.assertFalse(self.trie.starts_with("apq")) | ||
|
||
def test_multiple_words(self): | ||
words = ["apple", "app", "apricot", "banana", "bat"] | ||
for word in words: | ||
self.trie.insert(word) | ||
|
||
for word in words: | ||
self.assertTrue(self.trie.search(word)) | ||
|
||
self.assertTrue(self.trie.starts_with("ap")) | ||
self.assertTrue(self.trie.starts_with("ba")) | ||
self.assertFalse(self.trie.starts_with("c")) | ||
|
||
def test_empty_string(self): | ||
self.trie.insert("") | ||
self.assertTrue(self.trie.search("")) | ||
self.assertTrue(self.trie.starts_with("")) | ||
|
||
if __name__ == "__main__": | ||
unittest.main() |