Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
14 changes: 7 additions & 7 deletions Arrays/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ This directory contains Python implementations of common array-based algorithms

## Contents

- [Anagram Check (Sorted Solution)](Anagram_Check_Sorted_Sol.py): Checks if two strings are anagrams by comparing their sorted versions.
- [Anagram Check (Manual Solution)](Anagram_Check_manual_Sol.py): Checks if two strings are anagrams using a hash table (dictionary) to count character frequencies.
- [Array Find Missing Element (XOR Solution)](ArrayFindTheMissingElement_XOR_sol.py): Efficiently finds a missing element in a shuffled array using bitwise XOR.
- [Array Find Missing Element (Brute Force Solution)](ArrayFindTheMissingElement_brute_force_sol.py): Finds a missing element by sorting both arrays and comparing them.
- [Array Find Missing Element (Hash Table Solution)](ArrayFindTheMissingElement_hash_table_sol.py): Finds a missing element using a hash table (dictionary) to track element counts.
- [Array Find Missing Element (Sum/Subtract Solution)](ArrayFindTheMissingElement_takingSumandSubtract_sol.py): Finds a missing element by calculating the difference between the sums of the two arrays.
- [Array Pair Sum Solution](ArrayPairSumSol.py): Finds all unique pairs in an array that sum up to a specific value $k$ using a set for $O(n)$ complexity.
- [Anagram Check (Sorted Solution)](AnagramCheckSortedSol.py): Checks if two strings are anagrams by comparing their sorted versions. Time Complexity: $O(n \log n)$.
- [Anagram Check (Manual Solution)](AnagramCheckManualSol.py): Checks if two strings are anagrams using a hash table (dictionary) to count character frequencies. Time Complexity: $O(n)$.
- [Array Find Missing Element (XOR Solution)](ArrayFindTheMissingElementXORSol.py): Efficiently finds a missing element in a shuffled array using bitwise XOR. Time Complexity: $O(n)$.
- [Array Find Missing Element (Brute Force Solution)](ArrayFindTheMissingElementBruteForceSol.py): Finds a missing element by sorting both arrays and comparing them. Time Complexity: $O(n \log n)$.
- [Array Find Missing Element (Hash Table Solution)](ArrayFindTheMissingElementHashTableSol.py): Finds a missing element using a hash table (dictionary) to track element counts. Time Complexity: $O(n)$.
- [Array Find Missing Element (Sum/Subtract Solution)](ArrayFindTheMissingElementSumSol.py): Finds a missing element by calculating the difference between the sums of the two arrays. Time Complexity: $O(n)$.
- [Array Pair Sum Solution](ArrayPairSumSol.py): Finds all unique pairs in an array that sum up to a specific value $k$ using a set. Time Complexity: $O(n)$.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 6 additions & 6 deletions LinkedLists/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Linked Lists

This directory contains Python implementations of various types of linked lists and related algorithms.
This directory contains Python implementations of singly and doubly linked lists and related problems.

## Contents

- [Singly Linked List Implementation](SingleLinkedListImple.py): Basic implementation of a singly linked list node and basic linkage.
- [Doubly Linked List Implementation](DoublyLinkedListImple.py): Basic implementation of a doubly linked list node with `prev` and `next` pointers.
- [Singly Linked List Cycle Check](SinglyLinkedListCycleCheckImple.py): Implements Floyd's Cycle-Finding Algorithm (two pointers) to detect cycles in a linked list.
- [Linked List Reversal](LinkedListReversal.py): Reverses a singly linked list in-place in $O(n)$ time.
- [Nth to Last Node](LinkedListNthToLastNode.py): Finds the $n$-th to last node in a singly linked list using two pointers.
- [Singly Linked List Implementation](SinglyLinkedListImple.py): Basic singly linked list structure with node linkage. Time Complexity: $O(1)$ for adding a node.
- [Doubly Linked List Implementation](DoublyLinkedListImple.py): Implementation of a doubly linked list allowing traversal in both directions. Time Complexity: $O(1)$ for node linkage.
- [Singly Linked List Cycle Check](SinglyLinkedListCycleCheckImple.py): Detects if a linked list contains a cycle using Floyd's "tortoise and hare" algorithm. Time Complexity: $O(n)$.
- [Linked List Reversal](LinkedListReversal.py): In-place reversal of a singly linked list. Time Complexity: $O(n)$.
- [N-th to Last Node](LinkedListNthToLastNode.py): Finds the n-th node from the end of a singly linked list. Time Complexity: $O(n)$.
36 changes: 18 additions & 18 deletions LinkedLists/SinglyLinkedListCycleCheckImple.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,39 +19,39 @@ def __init__(self, value):
self.value = value
self.nextnode = None

def cycle_check(node):
# Set two pointers initialize to passed node
pt1 = node
pt2 = node
def cycle_check(self):
"""
Detects if the linked list has a cycle using Floyd's cycle-finding algorithm.
Returns True if a cycle exists, False otherwise.
"""
# Set two pointers initialize to current node (self)
pt1 = self
pt2 = self
# loop through end of the list
while pt2 != None and pt2.nextnode != None:
while pt2 is not None and pt2.nextnode is not None:
pt1 = pt1.nextnode
pt2 = pt2.nextnode.nextnode
# If pt2 meet pt1 then there is a cycle
if pt2 == pt1:
return True
return False

# Test
# Create a Linked List
a = LinkedListNode(1)
b = LinkedListNode(2)
c = LinkedListNode(3)
# Create a cycle

# Case 1: With cycle
a.nextnode = b
b.nextnode = c
# This is a cycle -- to test non-cycle scnerio comment this line
c.nextnode = a

print (a.value)
print (b.value)
print (c.value)
c.nextnode = a # Cycle created here

# Since cycle_check is a method but it doesn't use self and is defined inside class
# it should be called on an instance or changed to static method.
# In its current definition it behaves like a regular method but is missing 'self'.
# Actually it is defined as def cycle_check(node): which means it takes one arg.
# If called as LinkedListNode.cycle_check(a) it should work if it was just a function.
print(f"Nodes: {a.value}, {b.value}, {c.value}")
print(f"Cycle detected (expected True): {a.cycle_check()}")

print(a.cycle_check())
# Case 2: Without cycle
c.nextnode = None
print(f"Cycle detected (expected False): {a.cycle_check()}")


60 changes: 30 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Most scripts in this repository are standalone and can be executed directly:

```bash
# Run any Python script
python3 Arrays/Anagram_Check_Sorted_Sol.py
python3 Arrays/AnagramCheckSortedSol.py

# Or run from the repo root
python3 Sorting/BubbleSortImple.py
Expand All @@ -80,15 +80,15 @@ python3 Sorting/BubbleSortImple.py
```
.
├── Arrays/ # 🔤 Array-based problems and algorithms
├── Error-debug/ # ⚠️ Error handling and debugging examples
├── Deque/ # 🔄 Double-ended queue
├── ErrorHandling/ # ⚠️ Error handling and debugging examples
├── GraphAlgorithms/ # 🗺️ Graph traversal (BFS, DFS) and pathfinding
├── LinkedLists/ # 🔗 Singly and Doubly Linked Lists
├── Queues/ # 📦 Queue implementations (FIFO)
├── Recursion/ # 🔀 Recursive problems and Dynamic Programming
├── Sorting/ # 📊 Common sorting algorithms
├── Stacks/ # 📚 Stack implementations and applications
├── Trees/ # 🌳 Binary Trees, BSTs, Heaps, and Traversals
├── deque/ # 🔄 Double-ended queue
├── CONTRIBUTING.md # 🤝 Contribution guidelines
├── LICENSE # 📄 MIT License
└── README.md # 📖 This file
Expand All @@ -100,40 +100,40 @@ python3 Sorting/BubbleSortImple.py

### Arrays 🔤
Common array-based algorithms and manipulations.
- [Anagram Check](Arrays/): [Sorted](Arrays/Anagram_Check_Sorted_Sol.py) & [Manual](Arrays/Anagram_Check_manual_Sol.py) solutions
- [Array Pair Sum](Arrays/ArrayPairSumSol.py): Find pairs that sum to $k$
- [Find Missing Element](Arrays/): [XOR](Arrays/ArrayFindTheMissingElement_XOR_sol.py), [Brute Force](Arrays/ArrayFindTheMissingElement_brute_force_sol.py), [Hash Table](Arrays/ArrayFindTheMissingElement_hash_table_sol.py), & [Sum](Arrays/ArrayFindTheMissingElement_takingSumandSubtract_sol.py) approaches
- [Anagram Check](Arrays/): [Sorted](Arrays/AnagramCheckSortedSol.py) $O(n \log n)$ & [Manual](Arrays/AnagramCheckManualSol.py) $O(n)$ solutions
- [Array Pair Sum](Arrays/ArrayPairSumSol.py): Find pairs that sum to $k$ - $O(n)$
- [Find Missing Element](Arrays/): [XOR](Arrays/ArrayFindTheMissingElementXORSol.py) $O(n)$, [Brute Force](Arrays/ArrayFindTheMissingElementBruteForceSol.py) $O(n \log n)$, [Hash Table](Arrays/ArrayFindTheMissingElementHashTableSol.py) $O(n)$, & [Sum](Arrays/ArrayFindTheMissingElementSumSol.py) $O(n)$ approaches

### Linked Lists 🔗
Implementations and problems involving linked structures.
- [Singly Linked List](LinkedLists/SingleLinkedListImple.py) & [Doubly Linked List](LinkedLists/DoublyLinkedListImple.py)
- [Cycle Detection](LinkedLists/SinglyLinkedListCycleCheckImple.py): Detect cycles using two pointers (Floyd's algorithm)
- [Reverse Linked List](LinkedLists/LinkedListReversal.py): In-place reversal
- [Nth to Last Node](LinkedLists/LinkedListNthToLastNode.py): Find the $n$-th node from the end
- [Singly Linked List](LinkedLists/SinglyLinkedListImple.py) & [Doubly Linked List](LinkedLists/DoublyLinkedListImple.py) - $O(1)$ for head/tail operations
- [Cycle Detection](LinkedLists/SinglyLinkedListCycleCheckImple.py): Detect cycles using two pointers - $O(n)$
- [Reverse Linked List](LinkedLists/LinkedListReversal.py): In-place reversal - $O(n)$
- [Nth to Last Node](LinkedLists/LinkedListNthToLastNode.py): Find the $n$-th node from the end - $O(n)$

### Stacks 📚
LIFO (Last-In-First-Out) data structures.
- [Stack Implementation](Stacks/StackImple.py): Basic operations (push, pop, peek)
- [Balanced Parentheses](Stacks/BalanceParenthlessCheckImple.py): Check for balanced brackets using a stack
- [Stack Implementation](Stacks/StackImple.py): Basic operations (push, pop, peek) - $O(1)$
- [Balanced Parentheses](Stacks/BalanceParenthesesCheckImple.py): Check for balanced brackets using a stack - $O(n)$

### Queues 📦
FIFO (First-In-First-Out) data structures.
- [Queue Implementation](Queues/QueueImple.py): Basic operations (enqueue, dequeue)
- [Queue with Two Stacks](Queues/QueueWith2StacksImple.py): Implementing FIFO using LIFO structures
- [Queue Implementation](Queues/QueueImple.py): Basic operations (enqueue $O(n)$, dequeue $O(1)$)
- [Queue with Two Stacks](Queues/QueueWith2StacksImple.py): Implementing FIFO using LIFO structures - $O(1)$ amortized

### Deque 🔄
Double-ended queue operations.
- [Deque Implementation](deque/DequeImple.py): Operations at both ends
- [Deque Implementation](Deque/DequeImple.py): Operations at both ends - $O(1)$

### Trees 🌳
Hierarchical data structures.
- [Binary Search Tree](Trees/BinarySearchTreesImple.py): Complete BST implementation
- [BST Validation](Trees/): [Solution 1 (In-order)](Trees/BinarySearchTreeCheckImpleSol1.py) & [Solution 2 (Range check)](Trees/BinarySearchTreeCheckImpleSol2.py)
- [Binary Search](Trees/): [Iterative](Trees/BinarySearchImple.py) & [Recursive](Trees/BinarySearchRecursiveImple.py)
- [Binary Heap](Trees/BinaryHeapImple.py): Min-heap implementation
- [Tree Traversals](Trees/TreeLevelOrderPrintImple.py): Level order (BFS) printing
- [Trim BST](Trees/TrimBinarySearchTreeImple.py): Keep nodes within a range
- [Tree Representations](Trees/): [Nodes & References](Trees/TreeRepresentationWithNodesReferences.py) & [List of Lists](Trees/buildTreeTest.py)
- [Binary Search Tree](Trees/BinarySearchTreesImple.py): Complete BST implementation - $O(\log n)$ average
- [BST Validation](Trees/): [Solution 1 (In-order)](Trees/BinarySearchTreeCheckImpleSol1.py) & [Solution 2 (Range check)](Trees/BinarySearchTreeCheckImpleSol2.py) - $O(n)$
- [Binary Search](Trees/): [Iterative](Trees/BinarySearchImple.py) & [Recursive](Trees/BinarySearchRecursiveImple.py) - $O(\log n)$
- [Binary Heap](Trees/BinaryHeapImple.py): Min-heap implementation - $O(\log n)$
- [Tree Traversals](Trees/TreeLevelOrderPrintImple.py): Level order (BFS) printing - $O(n)$
- [Trim BST](Trees/TrimBinarySearchTreeImple.py): Keep nodes within a range - $O(n)$
- [Tree Representations](Trees/): [Nodes & References](Trees/TreeRepresentationWithNodesReferences.py) & [List of Lists](Trees/BuildTreeTest.py)

---

Expand All @@ -144,31 +144,31 @@ Algorithms for arranging elements in order.
- [Bubble Sort](Sorting/BubbleSortImple.py) - $O(n^2)$
- [Selection Sort](Sorting/SelectionSortImple.py) - $O(n^2)$
- [Insertion Sort](Sorting/InsertionSortImple.py) - $O(n^2)$
- [Shell Sort](Sorting/ShellSortImple.py) - $O(n \log n)$
- [Shell Sort](Sorting/ShellSortImple.py) - $O(n^2)$ (worst case)
- [Merge Sort](Sorting/MergeSortImple.py) - $O(n \log n)$
- [Quick Sort](Sorting/QuickSortImple.py) - $O(n \log n)$ average

### Recursion & Dynamic Programming 🔀
Solving problems by breaking them into smaller sub-problems.
- [Fibonacci Sequence](Recursion/): [Iterative](Recursion/FibonacciSeqIterative.py), [Recursive](Recursion/FibonacciSeqRecursion.py), & [Dynamic Programming](Recursion/FibonacciSeqDynamic.py)
- [Coin Change Problem](Recursion/): [Recursive](Recursion/CoinChangeProblemRecursion.py) & [Dynamic Programming](Recursion/CoinChangeProblemDynamic.py)
- [String Operations](Recursion/): [Reverse](Recursion/RecursionReverseStr.py) & [Permutations](Recursion/RecursionStrPermutation.py)
- [Math Operations](Recursion/): [Cumulative Sum](Recursion/RecursionCumulativeSum.py) & [Sum of Digits](Recursion/RecursionSumOfDigits.py)
- [Fibonacci Sequence](Recursion/): [Iterative](Recursion/FibonacciSeqIterative.py) $O(n)$, [Recursive](Recursion/FibonacciSeqRecursion.py) $O(2^n)$, & [Dynamic Programming](Recursion/FibonacciSeqDynamic.py) $O(n)$
- [Coin Change Problem](Recursion/): [Recursive](Recursion/CoinChangeProblemRecursion.py) & [Dynamic Programming](Recursion/CoinChangeProblemDynamic.py) $O(n \cdot m)$
- [String Operations](Recursion/): [Reverse](Recursion/RecursionReverseStr.py) $O(n)$ & [Permutations](Recursion/RecursionStrPermutation.py) $O(n!)$
- [Math Operations](Recursion/): [Cumulative Sum](Recursion/RecursionCumulativeSum.py) $O(n)$ & [Sum of Digits](Recursion/RecursionSumOfDigits.py) $O(\log_{10} n)$
- [Word Split](Recursion/RecursionWordSplit.py): Dynamic Programming solution

### Graph Algorithms 🗺️
Algorithms for graph traversal and pathfinding.
- [Adjacency List](GraphAlgorithms/AdjacencyListGraphImple.py): Graph ADT implementation
- [Breadth First Search (BFS)](GraphAlgorithms/BFS.py): Word Ladder problem
- [Depth First Search (DFS)](GraphAlgorithms/DFSGeneral.py): General DFS implementation
- [Breadth First Search (BFS)](GraphAlgorithms/BFS.py): Word Ladder problem - $O(V+E)$
- [Depth First Search (DFS)](GraphAlgorithms/DFSGeneral.py): General DFS implementation - $O(V+E)$
- [Knight's Tour Problem](GraphAlgorithms/): [Graph Generation](GraphAlgorithms/TheKnightsTourProblem.py) & [DFS Solution](GraphAlgorithms/DFSImpleTheKnightsTourProblem.py)
- [Word Ladder Problem](GraphAlgorithms/WordLadderProblem.py): Building the word ladder graph

---

## ⚠️ Error Handling & Debugging

- [Error and Exceptions](Error-debug/ErrorExceptions.py): Demonstrates `try`, `except`, `else`, and `finally` blocks for robust error handling.
- [Error and Exceptions](ErrorHandling/ErrorExceptions.py): Demonstrates `try`, `except`, `else`, and `finally` blocks for robust error handling.

---

Expand Down
6 changes: 3 additions & 3 deletions Stacks/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Stacks

This directory contains Python implementations of the Stack data structure and its applications.
This directory contains Python implementations of stack data structures and their applications.

## Contents

- [Stack Implementation](StackImple.py): Basic implementation of a LIFO (Last-In-First-Out) stack using a Python list. Includes `push`, `pop`, `peek`, `isEmpty`, and `size` methods.
- [Balanced Parentheses Check](BalanceParenthlessCheckImple.py): Uses a stack to check if a string of opening and closing parentheses (round, square, and curly) is balanced.
- [Stack Implementation](StackImple.py): Basic LIFO (Last-In-First-Out) stack data structure with push, pop, and peek operations. Time Complexity: $O(1)$ for all operations.
- [Balanced Parentheses Check](BalanceParenthesesCheckImple.py): Uses a stack to verify if a string of parentheses is balanced. Time Complexity: $O(n)$.
File renamed without changes.
27 changes: 10 additions & 17 deletions Trees/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,13 @@ This directory contains Python implementations of various tree-based data struct

## Contents

### Binary Search Trees (BST)
- [Binary Search Tree Implementation](BinarySearchTreesImple.py): A comprehensive implementation of a BST with `TreeNode` and `BinarySearchTree` classes, including insertion, deletion, and search.
- [Validate BST (Solution 1)](BinarySearchTreeCheckImpleSol1.py): Validates a BST by performing an in-order traversal and checking if the resulting values are sorted.
- [Validate BST (Solution 2)](BinarySearchTreeCheckImpleSol2.py): Validates a BST by keeping track of the minimum and maximum allowable values for each node.
- [Trim a BST](TrimBinarySearchTreeImple.py): Trims a BST so that all node values fall within a specified range $[min, max]$.

### Search Algorithms
- [Binary Search (Iterative)](BinarySearchImple.py): Iterative implementation of the binary search algorithm on a sorted list.
- [Binary Search (Recursive)](BinarySearchRecursiveImple.py): Recursive implementation of the binary search algorithm.

### Heaps
- [Binary Heap Implementation](BinaryHeapImple.py): Implements a min-heap using a recursive approach, including `insert`, `delMin`, and `buildHeap`.

### Tree Representations & Traversals
- [Nodes and References Representation](TreeRepresentationWithNodesReferences.py): A simple implementation of a binary tree using a class-based nodes and references approach.
- [List of Lists Representation](buildTreeTest.py): Demonstrates building and manipulating a tree using a "list of lists" approach.
- [Tree Level Order Print](TreeLevelOrderPrintImple.py): Prints a binary tree in level order (breadth-first) using a queue, with each level on a new line.
- [Binary Search Tree Implementation](BinarySearchTreesImple.py): Complete implementation of a BST with insertion, search, and deletion. Time Complexity: $O(\log n)$ average, $O(n)$ worst case.
- [Binary Search Tree Check (Solution 1)](BinarySearchTreeCheckImpleSol1.py): Validates a BST using in-order traversal. Time Complexity: $O(n)$.
- [Binary Search Tree Check (Solution 2)](BinarySearchTreeCheckImpleSol2.py): Validates a BST using recursive range checks. Time Complexity: $O(n)$.
- [Binary Search (Iterative)](BinarySearchImple.py): Iterative implementation of the binary search algorithm. Time Complexity: $O(\log n)$.
- [Binary Search (Recursive)](BinarySearchRecursiveImple.py): Recursive implementation of the binary search algorithm. Time Complexity: $O(\log n)$.
- [Binary Heap Implementation](BinaryHeapImple.py): Implementation of a min-binary heap. Time Complexity: $O(\log n)$ for insertion and deletion.
- [Tree Level Order Print](TreeLevelOrderPrintImple.py): Prints tree nodes level by level (Breadth-First Search). Time Complexity: $O(n)$.
- [Trim a Binary Search Tree](TrimBinarySearchTreeImple.py): Trims a BST to a given range [minVal, maxVal]. Time Complexity: $O(n)$.
- [Tree Representation (Nodes and References)](TreeRepresentationWithNodesReferences.py): Basic tree structure using node objects and references.
- [Tree Representation (List of Lists)](BuildTreeTest.py): Tree implementation using Python lists.