├── General
├── Sliding Window.pdf
├── Big O Categorization.pdf
├── Steps for Solving Coding Challenges.pdf
├── Divide and Conquer.md
├── Steps for Solving Coding Challenges.md
├── Solving Strategies.md
└── Tail Recursion.md
├── 6. Binary Trees
├── Learning Material
│ ├── images
│ │ ├── bfs.png
│ │ └── dfs.png
│ ├── 1. Tree Traversals
│ │ ├── In-order.md
│ │ ├── Pre-order.md
│ │ ├── Binary Tree Guide.md
│ │ ├── Post-order.md
│ │ ├── Depth First Search.md
│ │ ├── Breadth First Search.md
│ │ └── Binary Tree Class Code.py
│ └── 2. Heaps - Priority Queues
│ │ ├── Insertion (Sift Up).md
│ │ ├── Priority Queue.py
│ │ ├── Deletion (Sift Down).md
│ │ └── Heaps.md
├── 3. Right Side View of Tree
│ ├── Right Side View of Tree.pdf
│ ├── right-side-view-of-tree-dfs.py
│ └── right-side-view-of-tree-bfs.py
├── 4. Count Complete Tree Nodes
│ ├── Count Complete Tree Nodes.pdf
│ ├── count-complete-tree-nodes-brute-force-bfs.py
│ ├── count-complete-tree-nodes-brute-force-dfs.py
│ └── count-complete-tree-nodes-optimal.py
├── 2. Level Order of a Binary Tree
│ ├── Level Order of Binary Tree.pdf
│ └── level-order-of-binary-tree.py
├── 5. Validate Binary Search Tree
│ ├── Validate Binary Search Tree.pdf
│ ├── validate-binary-search-tree-brute-force.py
│ └── validate-binary-search-tree-optimal.py
└── 1. Maximum Depth of a Binary Tree
│ ├── Maximum Depth of Binary Tree.pdf
│ ├── maximum-depth-of-a-binary-tree-brute-force.py
│ └── maximum-depth-of-a-binary-tree-optimal.py
├── 8. Graphs
├── 2. Course Schedule
│ ├── Course Schedule.pdf
│ └── course-schedule.py
├── 3. Network Delay Time
│ ├── Network Delay Time.pdf
│ └── network-delay-time-dynamic-programming.py
└── 1. Time Needed to Inform All Employees
│ ├── Time Needed to Inform All Employees.pdf
│ └── time-needed-to-inform-all-employees.py
├── 2. Strings
├── 3. Valid Palindrome
│ ├── Valid Palindrome.pdf
│ ├── valid-palindrome-optimal.py
│ └── valid-palindrome-brute-force.py
├── 1. Backspace String Compare
│ ├── Backspace String Compare.pdf
│ ├── backspace-string-compare-brute-force.py
│ └── backspace-string-compare-optimal.py
├── 4. Valid Palindrome II - Almost Palindrome
│ ├── Valid Palindrome II - Almost Palindrome.pdf
│ ├── valid-palindrome-II-brute-force.py
│ └── valid-palindrome-II-optimal.py
├── 2. Longest Substring without Repeating Characters
│ ├── Longest Substring without Repeating Characters.pdf
│ ├── longest-substring-without-repeating-characters-brute-force.py
│ └── longest-substring-without-repeating-characters-optimal.py
└── Identify Palindrome Techniques.md
├── 7. 2D Arrays
├── 2. Rotting Oranges
│ ├── Rotting Oranges.pdf
│ └── rotting-oranges.py
├── 3. Walls and Gates
│ ├── Walls and Gates.pdf
│ └── walls-and-gates.py
└── 1. Number of Islands
│ ├── Number of Islands.pdf
│ └── number-of-islands.py
├── 9. Dynamic Programming
├── 1. Staircase
│ └── Staircase.pdf
└── 2. Knight Probability in Chessboard
│ └── Knight Probability in Chessboard.pdf
├── 1. Arrays
├── 3. Trapping Rain Water
│ ├── Trapping Rain Water.pdf
│ ├── trapping-rain-water-brute-force.py
│ └── trapping-rain-water-optimal.py
├── 2. Container with Most Water
│ ├── Container with Most Water.pdf
│ ├── container-with-most-water-optimal.py
│ └── container-with-most-water-brute-force.py
└── 1. Two Sum
│ ├── two-sum-optimal.py
│ └── two-sum-brute-force.py
├── 4. Stacks + Queues
├── 1. Valid Parentheses
│ ├── Valid Parentheses.pdf
│ └── valid-parentheses.py
├── 3. Implement Queues using Stacks
│ ├── Implement Queues using Stacks.pdf
│ └── implement-queues-using-stacks.py
└── 2. Minimum Remove to Make Valid Parentheses
│ ├── Minimum Remove to Make Vaild Parentheses.pdf
│ ├── minimum-remove-to-make-valid-parentheses-optimal.py
│ └── minimum-remove-to-make-valid-parentheses-brute-force.py
├── 3. Linked Lists
├── 1. Reverse a Linked List
│ ├── Reverse a Linked List.pdf
│ ├── reverse-a-linked-list-optimal.py
│ └── reverse-a-linked-list-brute-force.py
├── 4. Linked List Cycle (I and II)
│ ├── Linked List Cycle (I and II).pdf
│ ├── linked-list-cycle-I.py
│ └── linked-list-cycle-II.py
├── 3. Merge a Multi-level Doubly Linked List
│ ├── Merge Multi-level Doubly Linked List.pdf
│ └── merge-multi-level-doubly-linked-list.py
└── 2. Reverse Linked Lists II - M, N Reversals
│ ├── Reversed Linked Lists II_ M, N Reversals.pdf
│ └── reverse-linked-lists-II-m-n-reversals.py
├── 5. Recursion + Sortings
├── 1. Kth Largest Element in an Array
│ ├── Kth Largest Element in an Array.pdf
│ ├── kth-largest-element-in-an-array-brute-force.py
│ └── kth-largest-element-in-an-array-optimal.py
├── 2. Find First and Last Position of Element in Sorted Array
│ ├── Find First and Last Position of Element in Sorted Array.pdf
│ ├── find-first-and-last-position-of-element-in-sorted-array-iterative.py
│ └── find-first-and-last-position-of-element-in-sorted-array-recursive.py
└── Learning Material
│ ├── 1. Sorting + Searching.md
│ ├── Hoarse's QuickSelect Algorithm.md
│ ├── Binary Search.md
│ ├── Insertion Sort.md
│ ├── Selection Sort.md
│ └── Bubble Sort.md
└── README.md
/General/Sliding Window.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/General/Sliding Window.pdf
--------------------------------------------------------------------------------
/General/Big O Categorization.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/General/Big O Categorization.pdf
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/images/bfs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/6. Binary Trees/Learning Material/images/bfs.png
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/images/dfs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/6. Binary Trees/Learning Material/images/dfs.png
--------------------------------------------------------------------------------
/8. Graphs/2. Course Schedule/Course Schedule.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/8. Graphs/2. Course Schedule/Course Schedule.pdf
--------------------------------------------------------------------------------
/General/Steps for Solving Coding Challenges.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/General/Steps for Solving Coding Challenges.pdf
--------------------------------------------------------------------------------
/2. Strings/3. Valid Palindrome/Valid Palindrome.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/2. Strings/3. Valid Palindrome/Valid Palindrome.pdf
--------------------------------------------------------------------------------
/7. 2D Arrays/2. Rotting Oranges/Rotting Oranges.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/7. 2D Arrays/2. Rotting Oranges/Rotting Oranges.pdf
--------------------------------------------------------------------------------
/7. 2D Arrays/3. Walls and Gates/Walls and Gates.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/7. 2D Arrays/3. Walls and Gates/Walls and Gates.pdf
--------------------------------------------------------------------------------
/9. Dynamic Programming/1. Staircase/Staircase.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/9. Dynamic Programming/1. Staircase/Staircase.pdf
--------------------------------------------------------------------------------
/1. Arrays/3. Trapping Rain Water/Trapping Rain Water.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/1. Arrays/3. Trapping Rain Water/Trapping Rain Water.pdf
--------------------------------------------------------------------------------
/7. 2D Arrays/1. Number of Islands/Number of Islands.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/7. 2D Arrays/1. Number of Islands/Number of Islands.pdf
--------------------------------------------------------------------------------
/8. Graphs/3. Network Delay Time/Network Delay Time.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/8. Graphs/3. Network Delay Time/Network Delay Time.pdf
--------------------------------------------------------------------------------
/4. Stacks + Queues/1. Valid Parentheses/Valid Parentheses.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/4. Stacks + Queues/1. Valid Parentheses/Valid Parentheses.pdf
--------------------------------------------------------------------------------
/3. Linked Lists/1. Reverse a Linked List/Reverse a Linked List.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/3. Linked Lists/1. Reverse a Linked List/Reverse a Linked List.pdf
--------------------------------------------------------------------------------
/1. Arrays/2. Container with Most Water/Container with Most Water.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/1. Arrays/2. Container with Most Water/Container with Most Water.pdf
--------------------------------------------------------------------------------
/2. Strings/1. Backspace String Compare/Backspace String Compare.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/2. Strings/1. Backspace String Compare/Backspace String Compare.pdf
--------------------------------------------------------------------------------
/6. Binary Trees/3. Right Side View of Tree/Right Side View of Tree.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/6. Binary Trees/3. Right Side View of Tree/Right Side View of Tree.pdf
--------------------------------------------------------------------------------
/6. Binary Trees/4. Count Complete Tree Nodes/Count Complete Tree Nodes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/6. Binary Trees/4. Count Complete Tree Nodes/Count Complete Tree Nodes.pdf
--------------------------------------------------------------------------------
/6. Binary Trees/2. Level Order of a Binary Tree/Level Order of Binary Tree.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/6. Binary Trees/2. Level Order of a Binary Tree/Level Order of Binary Tree.pdf
--------------------------------------------------------------------------------
/6. Binary Trees/5. Validate Binary Search Tree/Validate Binary Search Tree.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/6. Binary Trees/5. Validate Binary Search Tree/Validate Binary Search Tree.pdf
--------------------------------------------------------------------------------
/2. Strings/3. Valid Palindrome/valid-palindrome-optimal.py:
--------------------------------------------------------------------------------
1 | import re
2 | def isPalindrome(self, s):
3 | """
4 | :type s: str
5 | :rtype: bool
6 | """
7 | s = re.sub(r'[^a-zA-Z0-9]', '', s.lower())
8 | return s == s[::-1]
--------------------------------------------------------------------------------
/3. Linked Lists/4. Linked List Cycle (I and II)/Linked List Cycle (I and II).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/3. Linked Lists/4. Linked List Cycle (I and II)/Linked List Cycle (I and II).pdf
--------------------------------------------------------------------------------
/6. Binary Trees/1. Maximum Depth of a Binary Tree/Maximum Depth of Binary Tree.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/6. Binary Trees/1. Maximum Depth of a Binary Tree/Maximum Depth of Binary Tree.pdf
--------------------------------------------------------------------------------
/4. Stacks + Queues/3. Implement Queues using Stacks/Implement Queues using Stacks.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/4. Stacks + Queues/3. Implement Queues using Stacks/Implement Queues using Stacks.pdf
--------------------------------------------------------------------------------
/8. Graphs/1. Time Needed to Inform All Employees/Time Needed to Inform All Employees.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/8. Graphs/1. Time Needed to Inform All Employees/Time Needed to Inform All Employees.pdf
--------------------------------------------------------------------------------
/5. Recursion + Sortings/1. Kth Largest Element in an Array/Kth Largest Element in an Array.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/5. Recursion + Sortings/1. Kth Largest Element in an Array/Kth Largest Element in an Array.pdf
--------------------------------------------------------------------------------
/9. Dynamic Programming/2. Knight Probability in Chessboard/Knight Probability in Chessboard.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/9. Dynamic Programming/2. Knight Probability in Chessboard/Knight Probability in Chessboard.pdf
--------------------------------------------------------------------------------
/General/Divide and Conquer.md:
--------------------------------------------------------------------------------
1 | # Divide and Conquer
2 | ## General Steps
3 | 1. Multi-branched recursion (splits the data into multiple parts)
4 | 2. Breaks problem into multiple sub-problems
5 | 3. Combines solutions of sub problems into the solution for original problem
--------------------------------------------------------------------------------
/2. Strings/4. Valid Palindrome II - Almost Palindrome/Valid Palindrome II - Almost Palindrome.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/2. Strings/4. Valid Palindrome II - Almost Palindrome/Valid Palindrome II - Almost Palindrome.pdf
--------------------------------------------------------------------------------
/3. Linked Lists/3. Merge a Multi-level Doubly Linked List/Merge Multi-level Doubly Linked List.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/3. Linked Lists/3. Merge a Multi-level Doubly Linked List/Merge Multi-level Doubly Linked List.pdf
--------------------------------------------------------------------------------
/3. Linked Lists/2. Reverse Linked Lists II - M, N Reversals/Reversed Linked Lists II_ M, N Reversals.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/3. Linked Lists/2. Reverse Linked Lists II - M, N Reversals/Reversed Linked Lists II_ M, N Reversals.pdf
--------------------------------------------------------------------------------
/4. Stacks + Queues/2. Minimum Remove to Make Valid Parentheses/Minimum Remove to Make Vaild Parentheses.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/4. Stacks + Queues/2. Minimum Remove to Make Valid Parentheses/Minimum Remove to Make Vaild Parentheses.pdf
--------------------------------------------------------------------------------
/2. Strings/2. Longest Substring without Repeating Characters/Longest Substring without Repeating Characters.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/2. Strings/2. Longest Substring without Repeating Characters/Longest Substring without Repeating Characters.pdf
--------------------------------------------------------------------------------
/General/Steps for Solving Coding Challenges.md:
--------------------------------------------------------------------------------
1 | # Steps for Solving Coding Challenges
2 | ## Intro
3 | 1. Verify Constraints
4 | 2. Create Testcases
5 | ## Brute Force + Optimal
6 | 1. Brainstorming & Pattern Observations
7 | 2. Pseudocode
8 | 3. Code
9 | 4. Run testcases against code
10 | 5. Analyze time + space complexity
11 |
12 |
--------------------------------------------------------------------------------
/2. Strings/3. Valid Palindrome/valid-palindrome-brute-force.py:
--------------------------------------------------------------------------------
1 | import re
2 | def isPalindrome(self, s):
3 | """
4 | :type s: str
5 | :rtype: bool
6 | """
7 | s = re.sub(r'[^a-zA-Z0-9]', '', s.lower())
8 | for i in range(len(s)/2):
9 | if s[i] != s[len(s)-1-i]:
10 | return False
11 | return True
--------------------------------------------------------------------------------
/2. Strings/Identify Palindrome Techniques.md:
--------------------------------------------------------------------------------
1 | ## Identify Palindrome Techniques:
2 | 1. Initialize left and right pointers at first and last index and traverse inwards until center to see if chars match
3 | 2. Initialize left and right pointers at center and traverse outwards to see if chars match
4 | 3. Flip given string and check if it matches given string
--------------------------------------------------------------------------------
/5. Recursion + Sortings/2. Find First and Last Position of Element in Sorted Array/Find First and Last Position of Element in Sorted Array.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandhya-veludandi/master-the-coding-interview/HEAD/5. Recursion + Sortings/2. Find First and Last Position of Element in Sorted Array/Find First and Last Position of Element in Sorted Array.pdf
--------------------------------------------------------------------------------
/2. Strings/1. Backspace String Compare/backspace-string-compare-brute-force.py:
--------------------------------------------------------------------------------
1 | def resultString(self, s):
2 | result = []
3 | i = 0
4 | while i < len(s):
5 | if s[i] == '#':
6 | if i > 0 and len(result) > 0:
7 | result.pop()
8 | else:
9 | result.append(s[i])
10 | i += 1
11 | return result
--------------------------------------------------------------------------------
/1. Arrays/2. Container with Most Water/container-with-most-water-optimal.py:
--------------------------------------------------------------------------------
1 | def maxArea(self, height):
2 | """
3 | :type height: List[int]
4 | :rtype: int
5 | """
6 | maxArea = 0
7 | a_index = 0
8 | b_index = len(height)-1
9 | while a_index != b_index:
10 | a = height[a_index]
11 | b = height[b_index]
12 | newArea = min(a, b)*(b_index-a_index)
13 | maxArea = max(maxArea, newArea)
14 | if a < b:
15 | a_index += 1
16 | else:
17 | b_index -= 1
18 | return maxArea
--------------------------------------------------------------------------------
/3. Linked Lists/1. Reverse a Linked List/reverse-a-linked-list-optimal.py:
--------------------------------------------------------------------------------
1 | class ListNode(object):
2 | def __init__(self, val=0, next=None):
3 | self.val = val
4 | self.next = next
5 |
6 | class Solution(object):
7 | def reverseList(self, head):
8 | """
9 | :type head: ListNode
10 | :rtype: ListNode
11 | """
12 | prev = None
13 | curr = head
14 | while(curr):
15 | temp = curr.next
16 | curr.next = prev
17 | prev = curr
18 | curr = temp
19 | return prev
--------------------------------------------------------------------------------
/1. Arrays/2. Container with Most Water/container-with-most-water-brute-force.py:
--------------------------------------------------------------------------------
1 | def maxArea(self, height):
2 | """
3 | :type height: List[int]
4 | :rtype: int
5 | """
6 | maxArea = 0
7 | for i in range(len(height)-1):
8 | curr_height = height[i]
9 | j = i + 1
10 | while j in range(len(height)):
11 | other_height = height[j]
12 | length = min(curr_height, other_height)
13 | width = j - i
14 | newArea = length*width
15 | maxArea = max(maxArea, newArea)
16 | j += 1
17 | return maxArea
--------------------------------------------------------------------------------
/3. Linked Lists/4. Linked List Cycle (I and II)/linked-list-cycle-I.py:
--------------------------------------------------------------------------------
1 | class ListNode(object):
2 | def __init__(self, val=0, next=None):
3 | self.val = val
4 | self.next = next
5 |
6 | class Solution(object):
7 | def hasCycle(self, head):
8 | """
9 | :type head: ListNode
10 | :rtype: bool
11 | """
12 | curr = head
13 | prev = head
14 | while curr != None and curr.next != None:
15 | curr = curr.next.next
16 | prev = prev.next
17 | if curr != None and curr == prev:
18 | return True
19 | return False
--------------------------------------------------------------------------------
/1. Arrays/1. Two Sum/two-sum-optimal.py:
--------------------------------------------------------------------------------
1 | def twoSum(self, nums, target):
2 | """
3 | :type nums: List[int]
4 | :type target: int
5 | :rtype: List[int]
6 | """
7 | #Hashmap solution
8 | #Hashmap will contain previously calculated ntfs
9 | hashmap = {}
10 | for i in range(len(nums)):
11 | curr_num = nums[i]
12 | numToFind = target - curr_num
13 | #if curr_num in hashmap, return the indices
14 | if curr_num in hashmap:
15 | return [i, hashmap[curr_num]]
16 | #otherwise, add the new ntf to the hashmap
17 | hashmap[numToFind] = i
18 | return None
--------------------------------------------------------------------------------
/4. Stacks + Queues/1. Valid Parentheses/valid-parentheses.py:
--------------------------------------------------------------------------------
1 | def isValid(self, s):
2 | """
3 | :type s: str
4 | :rtype: bool
5 | """
6 | if len(s) % 2 == 1: return False
7 |
8 | stack = []
9 | valid = {
10 | ')': '(',
11 | ']': '[',
12 | '}': '{'
13 | }
14 | for c in s:
15 | if c not in valid:
16 | stack.append(c)
17 | elif stack != [] and valid[c] == stack[-1]:
18 | stack.pop()
19 | else:
20 | return False
21 | return stack == []
--------------------------------------------------------------------------------
/2. Strings/4. Valid Palindrome II - Almost Palindrome/valid-palindrome-II-brute-force.py:
--------------------------------------------------------------------------------
1 | import re
2 | def validPalindrome(self, s):
3 | """
4 | :type s: str
5 | :rtype: bool
6 | """
7 | s = re.sub(r'[^a-zA-Z0-9]', '', s.lower())
8 | if s == s[::-1]:
9 | return True
10 | for i in range(len(s)/2):
11 | if s[i] != s[len(s)-1-i]:
12 | #add two possible palindromes
13 | #one without i char
14 | s1 = s[:i]+s[i+1:]
15 | #one without len(s)-1-i char
16 | s2 = s[:len(s)-1-i]+s[len(s)-i:]
17 |
18 | return s1 == s1[::-1] or s2 == s2[::-1]
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/1. Tree Traversals/In-order.md:
--------------------------------------------------------------------------------
1 | # DFS In-order Traversal
2 | ## Order
3 | left, root, right
4 | ## Example
5 | ```
6 | 9
7 | 4 20
8 | 1 6 15 170
9 |
10 | Visited Order:
11 | [1, 4, 6, 9, 15, 20, 170]
12 | ```
13 |
14 | ## Code
15 | ```Python
16 | def traverseInOrder(self, node, list):
17 | if node != None:
18 | if node.left:
19 | self.traverseInOrder(node.left, list)
20 | list.append(node.val)
21 | if node.right:
22 | self.traverseInOrder(node.right, list)
23 | return list
24 |
25 | def dfsInOrder(self):
26 | return self.traverseInOrder(self.getRoot(), [])
27 | ```
28 |
--------------------------------------------------------------------------------
/2. Strings/2. Longest Substring without Repeating Characters/longest-substring-without-repeating-characters-brute-force.py:
--------------------------------------------------------------------------------
1 | def longestSubstringWithoutRepeats(s):
2 | """
3 | :type s: str
4 | :rtype: int
5 | """
6 | curr_index = 0
7 | maxLength = 0
8 | chars = {}
9 | while curr_index < len(s):
10 | if s[curr_index] not in chars:
11 | chars[s[curr_index]] = curr_index
12 | else:
13 | curr_index = chars[s[curr_index]]+1
14 | chars = {}
15 | chars[s[curr_index]] = curr_index
16 | maxLength = max(maxLength, len(chars))
17 | curr_index += 1
18 | return maxLength
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/1. Tree Traversals/Pre-order.md:
--------------------------------------------------------------------------------
1 | # DFS Pre-order Traversal
2 | ## Order
3 | root, left, right
4 | ## Example
5 | ```
6 | 9
7 | 4 20
8 | 1 6 15 170
9 |
10 | Visited Order:
11 | [9, 4, 1, 6, 20, 15, 170]
12 | ```
13 |
14 | ## Code
15 | ```Python
16 | def traversePreOrder(self, node, list):
17 | if node != None:
18 | list.append(node.val)
19 | if node.left:
20 | self.traversePreOrder(node.left, list)
21 | if node.right:
22 | self.traversePreOrder(node.right, list)
23 | return list
24 |
25 | def dfsPreOrder(self):
26 | return self.traversePreOrder(self.getRoot(), [])
27 | ```
28 |
--------------------------------------------------------------------------------
/2. Strings/4. Valid Palindrome II - Almost Palindrome/valid-palindrome-II-optimal.py:
--------------------------------------------------------------------------------
1 | import re
2 | def validPalindrome(self, s):
3 | """
4 | :type s: str
5 | :rtype: bool
6 | """
7 | s = re.sub(r'[^a-zA-Z0-9]', '', s.lower())
8 | if s == s[::-1]:
9 | return True
10 | i = 0
11 | while i < len(s)/2+1:
12 | if s[i] != s[len(s)-1-i]:
13 | #two possible palindromes
14 | #one with i char and without len(s)-1-i
15 | s1 = s[i:len(s)-1-i]
16 | #one with len(s)-1-i char and without i
17 | s2 = s[i+1:len(s)-i]
18 | return s1 == s1[::-1] or s2 == s2[::-1]
19 | i += 1
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/1. Tree Traversals/Binary Tree Guide.md:
--------------------------------------------------------------------------------
1 | # Binary Tree Guide
2 | ## Traversals
3 | * bfs
4 | * dfs
5 | * pre order
6 | * in order
7 | * post order
8 | ## Questions to Ask:
9 | * need to traverse tree?
10 | * bfs: node looking for closer to root rather than leaf nodes (bc bfs travels one by one level)
11 | * dfs: node looking for closer to leaf nodes rather than root (bc follows all the children nodes)
12 | * do we care about diff traversals? care about order in which value is visited?
13 | * pre order: value, left, right
14 | * in order: left, value, right
15 | * post order: left, right, value
16 |
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/1. Tree Traversals/Post-order.md:
--------------------------------------------------------------------------------
1 | # DFS Post-order Traversal
2 | ## Order
3 | left, right, root
4 |
5 | ## Example
6 | ```
7 | 9
8 | 4 20
9 | 1 6 15 170
10 |
11 | Visited Order:
12 | [1, 6, 4, 15, 170, 20, 9]
13 | ```
14 |
15 | ## Code
16 | ```Python
17 | def traversePostOrder(self, node, list):
18 | if node != None:
19 | if node.left:
20 | self.traversePostOrder(node.left, list)
21 | if node.right:
22 | self.traversePostOrder(node.right, list)
23 | list.append(node.val)
24 | return list
25 |
26 | def dfsPostOrder(self):
27 | return self.traversePostOrder(self.getRoot(), [])
28 | ```
29 |
--------------------------------------------------------------------------------
/6. Binary Trees/1. Maximum Depth of a Binary Tree/maximum-depth-of-a-binary-tree-brute-force.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def maxDepth(self, root):
9 | """
10 | :type root: TreeNode
11 | :rtype: int
12 | """
13 | if root == None:
14 | return 0
15 |
16 | left = 1 + self.maxDepth(root.left)
17 | right = 1 + self.maxDepth(root.right)
18 | if left < right:
19 | return right
20 | else:
21 | return left
--------------------------------------------------------------------------------
/5. Recursion + Sortings/Learning Material/1. Sorting + Searching.md:
--------------------------------------------------------------------------------
1 | # Sorting + Searching
2 | When sort an array, have a lot of knowledge at each position:
3 | `[1, 2, 3, 4, 5, 6]`: at position 3 (number 4), then anything before position 3 is less than 4 and greater than 3 is more than 4
4 | ## Important
5 | * trade-offs between time + space complexity
6 | * which types of data does it best/worst sort on?
7 | * random
8 | * nearly sorted
9 | * reversed
10 | * few unique (many values that are the same)
11 | ## Sorts
12 | ### Elementary
13 | 1. Bubble Sort
14 | 2. Selection Sort
15 | 3. Insertion Sort
16 | ### Complex
17 | 1. Merge Sort
18 | 2. Quick Sort
19 | ## Searching
20 | 1. Binary Search
--------------------------------------------------------------------------------
/6. Binary Trees/1. Maximum Depth of a Binary Tree/maximum-depth-of-a-binary-tree-optimal.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def maxDepthHelper(self, root, count):
9 | if root == None:
10 | return count
11 | count += 1
12 | return max(self.maxDepthHelper(root.left, count), self.maxDepthHelper(root.right, count))
13 |
14 | def maxDepth(self, root):
15 | """
16 | :type root: TreeNode
17 | :rtype: int
18 | """
19 | return self.maxDepthHelper(root, 0)
--------------------------------------------------------------------------------
/2. Strings/2. Longest Substring without Repeating Characters/longest-substring-without-repeating-characters-optimal.py:
--------------------------------------------------------------------------------
1 | def longestSubstringWithoutRepeats(s):
2 | """
3 | :type s: str
4 | :rtype: int
5 | """
6 | chars = {}
7 | left = 0
8 | right = 0
9 | maxLength = 0
10 | while right < len(s):
11 | curr_char = s[right]
12 | prevSeenChar = -1
13 | if curr_char in chars:
14 | prevSeenChar = chars[curr_char]
15 | if prevSeenChar >= left:
16 | prevSeenChar += 1
17 | left = prevSeenChar
18 | chars[curr_char] = right
19 | maxLength = max(right-left+1, maxLength)
20 | right += 1
21 | return maxLength
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/1. Tree Traversals/Depth First Search.md:
--------------------------------------------------------------------------------
1 | # Depth First Search (DFS)
2 | Logic: visit all the children node first (classic example of search in tree, traverse thru left then right branch of node)
3 |
4 |
5 |
6 | ## Example:
7 | ```
8 | 101
9 | 33 105
10 | ```
11 |
12 | ## 3 Ways to Implement DFS:
13 | The order title refers to which order the root node comes in
14 | 1. Pre-order
15 |
16 | root, left, right:
17 | 101, 33, 105
18 |
19 | 2. In-order
20 |
21 | left , root, right
22 | 33, 101, 105
23 |
24 | 3. Post-order
25 |
26 | left, right , root
27 | 33, 105, 101
28 |
29 | Space Complexity: max tree depth / height
--------------------------------------------------------------------------------
/3. Linked Lists/1. Reverse a Linked List/reverse-a-linked-list-brute-force.py:
--------------------------------------------------------------------------------
1 | class ListNode(object):
2 | def __init__(self, val=0, next=None):
3 | self.val = val
4 | self.next = next
5 |
6 | class Solution(object):
7 | def reverseList(self, head):
8 | """
9 | :type head: ListNode
10 | :rtype: ListNode
11 | """
12 | if(head == None or head.next == None):
13 | return head
14 | #create new list
15 | newHead = None
16 | #create a new node and add it to the to the front of the list
17 | while head is not None:
18 | newNode = ListNode(val=head.val, next=newHead)
19 | newHead = newNode
20 | head = head.next
21 | return newHead
--------------------------------------------------------------------------------
/5. Recursion + Sortings/Learning Material/Hoarse's QuickSelect Algorithm.md:
--------------------------------------------------------------------------------
1 | # Hoarse's QuickSelect Algorithm
2 | Used to find the kth smallest element in unordered list.
3 | ```
4 | Given: [5, 3, 1, 6, 4, 2] and k = 4
5 | Final Answer with Quick Sort: [1, 2, 3, 4, 5, 6] → 4
6 | ```
7 | Logic: since we don’t care about sorting all elements, only sort on one half of the branch where we know k will be
8 |
9 | ## kth smallest
10 | [[1], 2, [5, 6, 4, 3]]
11 | partition = 2
12 | k = 4, sort only on the right branch
13 | ```
14 | if k < partition:
15 | sort on left branch
16 | elif k > partition:
17 | sort on right branch
18 | else:
19 | return arr[partition]
20 | ```
21 | ## kth largest
22 | Logic: simply change the k value so that it uses the same logic as kth smallest
23 | `k = len(arr) - k`
24 |
--------------------------------------------------------------------------------
/3. Linked Lists/4. Linked List Cycle (I and II)/linked-list-cycle-II.py:
--------------------------------------------------------------------------------
1 | class ListNode(object):
2 | def __init__(self, val=0, next=None):
3 | self.val = val
4 | self.next = next
5 |
6 | class Solution(object):
7 | def detectCycle(self, head):
8 | """
9 | :type head: ListNode
10 | :rtype: ListNode
11 | """
12 | curr = head
13 | prev = head
14 | while curr != None and curr.next != None:
15 | curr = curr.next.next
16 | prev = prev.next
17 | if curr != None and curr == prev:
18 | start = head
19 | while start != curr:
20 | start = start.next
21 | curr = curr.next
22 | return start
23 | return None
--------------------------------------------------------------------------------
/4. Stacks + Queues/2. Minimum Remove to Make Valid Parentheses/minimum-remove-to-make-valid-parentheses-optimal.py:
--------------------------------------------------------------------------------
1 | import re
2 | def minRemoveToMakeValid(self, s):
3 | """
4 | :type s: str
5 | :rtype: str
6 | """
7 | stackIndices = []
8 | s = list(s)
9 | print(s)
10 | i = 0
11 | while i < len(s):
12 | #if we have close parens match
13 | if stackIndices != [] and s[i] == ')' and s[stackIndices[-1]] == '(':
14 | stackIndices.pop()
15 | elif stackIndices == [] and s[i] == ')':
16 | del s[i]
17 | i -= 1
18 | elif s[i] == '(' or s[i] == ')':
19 | stackIndices.append(i)
20 | i += 1
21 |
22 | while stackIndices != []:
23 | idx = stackIndices.pop()
24 | del s[idx]
25 | return "".join(s)
--------------------------------------------------------------------------------
/6. Binary Trees/3. Right Side View of Tree/right-side-view-of-tree-dfs.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def helper(self, node, list, height):
9 | if node == None:
10 | return list
11 | height += 1
12 | if height - 1 == len(list):
13 | list.append(node.val)
14 |
15 | if node.right:
16 | self.helper(node.right, list, height)
17 |
18 | if node.left:
19 | self.helper(node.left, list, height)
20 |
21 | def rightSideView(self, root):
22 | """
23 | :type root: TreeNode
24 | :rtype: List[int]
25 | """
26 | return self.helper(root, [], 0)
--------------------------------------------------------------------------------
/1. Arrays/3. Trapping Rain Water/trapping-rain-water-brute-force.py:
--------------------------------------------------------------------------------
1 | def trap(self, height):
2 | """
3 | :type height: List[int]
4 | :rtype: int
5 | """
6 | total_water_amt = 0
7 | p = 0
8 | while p < len(height):
9 | #search for the max to the left of p
10 | maxL = p
11 | maxR = p
12 | i = p-1
13 | while i >= 0:
14 | if (height[i] > height[maxL]):
15 | maxL = i
16 | i -= 1
17 | j = p+1
18 | while j < len(height):
19 | if(height[j] > height[maxR]):
20 | maxR = j
21 | j += 1
22 |
23 | water_amt = min(height[maxL], height[maxR]) - height[p]
24 | if water_amt > 0:
25 | total_water_amt += water_amt
26 | p += 1
27 | return total_water_amt
--------------------------------------------------------------------------------
/5. Recursion + Sortings/2. Find First and Last Position of Element in Sorted Array/find-first-and-last-position-of-element-in-sorted-array-iterative.py:
--------------------------------------------------------------------------------
1 | def binarySearch(self, nums, left, right, target, ranges, prevMid):
2 | if nums == []:
3 | return [-1, -1]
4 | initialPos = self.binarySearch(nums, 0, len(nums)-1, target);
5 | if initialPos == -1: return [-1, -1];
6 | lowPos = initialPos
7 | highPos = initialPos
8 | tempLeft = None
9 | tempRight = None
10 | while lowPos != -1:
11 | #save the last time target was found
12 | tempLeft = lowPos
13 | lowPos = self.binarySearch(nums, 0, lowPos - 1, target)
14 |
15 | while highPos != -1:
16 | tempRight = highPos
17 | highPos = self.binarySearch(nums, highPos + 1, len(nums)-1, target)
18 |
19 | return [tempLeft, tempRight]
--------------------------------------------------------------------------------
/7. 2D Arrays/3. Walls and Gates/walls-and-gates.py:
--------------------------------------------------------------------------------
1 | class Solution(object):
2 | directions = [[-1, 0], [0, 1], [1, 0], [0, -1]]
3 | def wallsAndGates(self, a, n, m):
4 | for row in range(n):
5 | for col in range(m):
6 | if a[row][col] == 0:
7 | self.dfs(row, col, a, 0)
8 | return a
9 |
10 | def dfs(self, row, col, grid, steps):
11 | steps += 1
12 | for direction in self.directions:
13 | row1 = row + direction[0]
14 | col1 = col + direction[1]
15 | if row1 < 0 or row1 >= len(grid) or col1 < 0 or col1 >= len(grid[0]) or grid[row1][col1] <= 0 or steps > grid[row1][col1]:
16 | continue
17 | else:
18 | grid[row1][col1] = min(steps, grid[row1][col1])
19 | self.dfs(row1, col1, grid, steps)
--------------------------------------------------------------------------------
/1. Arrays/1. Two Sum/two-sum-brute-force.py:
--------------------------------------------------------------------------------
1 | def twoSum(self, nums, target):
2 | """
3 | :type nums: List[int]
4 | :type target: int
5 | :rtype: List[int]
6 | """
7 | results = []
8 | #Iterate thru all numbers except the last one in the outer for loop
9 | for i in range(len(nums)-1):
10 | #Pointer 1
11 | num = nums[i]
12 | #Based on pointer1's number, we're trying to find the number that will
13 | #add up to the target: numToFind = target - pointer1
14 | numToFind = target - num
15 | #Pointer 2
16 | j = i + 1
17 | #Iterate through the rest of the numbers
18 | while j in range(len(nums)):
19 | if nums[j] == numToFind:
20 | results.append(i)
21 | results.append(j)
22 | return results
23 | j += 1
24 | return None
--------------------------------------------------------------------------------
/General/Solving Strategies.md:
--------------------------------------------------------------------------------
1 | # Solving Strategies
2 | ## Iterative
3 | ### Data Structures
4 | 1. Arrays
5 | 2. Strings
6 | 3. Linked Lists
7 | 4. Stacks + Queues
8 | ### Strategies
9 | #### Pointers
10 | Note: pointers can begin anywhere in array (usually at first or last index)
11 | * Basic: pointers for outer and inner for loop (usually O(n^2))
12 | * Shifting Pointers:
13 | * 2 pointers at first and last index, conditionally move either one inward (usually O(n))
14 | * Skipping Pointers:
15 | * pointers skip over certain indices depending on condition
16 | #### Hashmaps
17 | Note: used to store 2 pieces information (key and value)
18 | ## Recursion
19 | ### Data Structures
20 | 1. 2d Arrays
21 | 2. Binary Trees
22 | 3. Heaps
23 | 4. Graphs
24 | ### Algorithmic Approaches
25 | 1. Sorting
26 | 2. Greedy Method
27 | 3. Divide & Conquer
28 | 4. Dynamic Programming
29 | 5. Backtracking
30 |
31 |
--------------------------------------------------------------------------------
/6. Binary Trees/4. Count Complete Tree Nodes/count-complete-tree-nodes-brute-force-bfs.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def countNodes(self, root):
9 | """
10 | :type root: TreeNode
11 | :rtype: int
12 | """
13 | if root == None: return 0
14 | queue = []
15 | curr = root
16 | queue.append(curr)
17 | orderOfNodesList = []
18 | while queue != []:
19 | curr = queue[0]
20 | orderOfNodesList.append(curr)
21 | queue = queue[1:]
22 | if curr.left:
23 | queue.append(curr.left)
24 | if curr.right != None:
25 | queue.append(curr.right)
26 | return len(orderOfNodesList)
--------------------------------------------------------------------------------
/4. Stacks + Queues/2. Minimum Remove to Make Valid Parentheses/minimum-remove-to-make-valid-parentheses-brute-force.py:
--------------------------------------------------------------------------------
1 | import re
2 | def minRemoveToMakeValid(self, s):
3 | """
4 | :type s: str
5 | :rtype: str
6 | """
7 | stackParens = []
8 | stackIndices = []
9 | for i in range(len(s)):
10 | char = s[i]
11 | #if we have close parens match
12 | if stackParens != [] and char == ')' and stackParens[-1] == '(':
13 | stackParens.pop()
14 | stackIndices.pop()
15 | elif char == '(' or char == ')':
16 | stackParens.append(char)
17 | stackIndices.append(i)
18 | #remove the parens using stackIndices
19 | arr1=[]
20 | for i in range(len(s)):
21 | arr1.append(i)
22 | new = filter(lambda i: i not in stackIndices, arr1)
23 | new_str = ""
24 | for i in new:
25 | new_str += s[i]
26 | return new_str
--------------------------------------------------------------------------------
/6. Binary Trees/4. Count Complete Tree Nodes/count-complete-tree-nodes-brute-force-dfs.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def countNodesHelper(self, root, count):
9 | if root == None:
10 | return 0
11 | else:
12 | count += 1
13 | leftSide = 0
14 | rightSide = 0
15 | if root.left != None:
16 | leftSide = self.countNodesHelper(root.left, 0)
17 | if root.right != None:
18 | rightSide = self.countNodesHelper(root.right, 0)
19 | count += (leftSide + rightSide)
20 | return count
21 | def countNodes(self, root):
22 | """
23 | :type root: TreeNode
24 | :rtype: int
25 | """
26 | return self.countNodesHelper(root, 0)
--------------------------------------------------------------------------------
/6. Binary Trees/5. Validate Binary Search Tree/validate-binary-search-tree-brute-force.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def inOrderTraversal(self, root, list):
9 | if root != None:
10 | if root.left:
11 | self.inOrderTraversal(root.left, list)
12 | list.append(root.val)
13 | if root.right:
14 | self.inOrderTraversal(root.right, list)
15 | return list
16 | def isValidBST(self, root):
17 | """
18 | :type root: TreeNode
19 | :rtype: bool
20 | """
21 | treeList = self.inOrderTraversal(root, [])
22 | tmpList = set(treeList)
23 | sortedList = sorted(treeList)
24 | noDuplicates = len(tmpList) == len(sortedList)
25 | return noDuplicates and sortedList == treeList
--------------------------------------------------------------------------------
/1. Arrays/3. Trapping Rain Water/trapping-rain-water-optimal.py:
--------------------------------------------------------------------------------
1 | def trap(self, height):
2 | """
3 | :type height: List[int]
4 | :rtype: int
5 | """
6 | total_water_amt = 0
7 | pL = 0
8 | pR = len(height)-1
9 | maxL = 0
10 | maxR = len(height)-1
11 | while(pL != pR):
12 | #where the left side has the shortest height
13 | if height[pL] <= height[pR]:
14 | #calculate water amt if true
15 | if height[maxL] > height[pL]:
16 | total_water_amt += height[maxL] - height[pL]
17 | #update max
18 | else:
19 | maxL = pL
20 | pL += 1
21 | #where the right side has the shortest height
22 | else:
23 | #calculate water amt if true
24 | if height[maxR] > height[pR]:
25 | total_water_amt += height[maxR] - height[pR]
26 | #update max
27 | else:
28 | maxR = pR
29 | pR -= 1
30 | return total_water_amt
--------------------------------------------------------------------------------
/3. Linked Lists/3. Merge a Multi-level Doubly Linked List/merge-multi-level-doubly-linked-list.py:
--------------------------------------------------------------------------------
1 | class Node(object):
2 | def __init__(self, val, prev, next, child):
3 | self.val = val
4 | self.prev = prev
5 | self.next = next
6 | self.child = child
7 |
8 | class Solution(object):
9 | def flatten(self, head):
10 | """
11 | :type head: Node
12 | :rtype: Node
13 | """
14 | curr = head
15 | while curr != None:
16 | print(curr.val)
17 | if curr.child != None:
18 | temp = curr.next
19 | curr.next = curr.child
20 | curr.child = None
21 | curr.next.prev = curr
22 | tail = curr
23 | while tail != None:
24 | if tail.next == None:
25 | break
26 | tail = tail.next
27 | tail.next = temp
28 | if temp != None:
29 | temp.prev = tail
30 | curr = curr.next
31 |
32 | return head
--------------------------------------------------------------------------------
/5. Recursion + Sortings/1. Kth Largest Element in an Array/kth-largest-element-in-an-array-brute-force.py:
--------------------------------------------------------------------------------
1 | def partition(self, arr, low, high):
2 | #holds the place of where the pivot should be
3 | i = low
4 | #scans and compares #s against pivot
5 | j = low
6 | #pivot is rightmost element
7 | pivot = arr[high]
8 | while j < high:
9 | if arr[j] < arr[high]:
10 | if i != j:
11 | arr[i], arr[j] = arr[j], arr[i]
12 | i += 1
13 | j += 1
14 | else:
15 | j += 1
16 | arr[i], arr[high] = pivot, arr[i]
17 | return i
18 |
19 | def quickSort(self, arr, low, high, k):
20 | if low < high:
21 | partition = self.partition(arr, low, high)
22 | if k == len(arr)-partition:
23 | return arr[-k]
24 | self.quickSort(arr, low, partition-1, k)
25 | self.quickSort(arr, partition+1, high, k)
26 | return arr[-k]
27 |
28 | def findKthLargest(self, arr, k):
29 | """
30 | :type nums: List[int]
31 | :type k: int
32 | :rtype: int
33 | """
34 | return self.quickSort(arr, 0, len(arr)-1, k)
--------------------------------------------------------------------------------
/8. Graphs/3. Network Delay Time/network-delay-time-dynamic-programming.py:
--------------------------------------------------------------------------------
1 | import sys
2 | class Solution(object):
3 | def networkDelayTime(self, times, n, k):
4 | """
5 | :type times: List[List[int]]
6 | :type n: int
7 | :type k: int
8 | :rtype: int
9 | """
10 | distance = {}
11 | k = k - 1
12 |
13 | for i in range(n):
14 | distance[i] = sys.maxint
15 |
16 | vertex = k
17 | distance[k] = 0
18 |
19 | for i in range(n):
20 | count = 0
21 | for time in times:
22 | src = time[0] - 1
23 | dest = time[1] - 1
24 | wt = time[2]
25 |
26 | if distance[src] == sys.maxint:
27 | continue
28 | else:
29 | if distance[src] + wt < distance[dest]:
30 | distance[dest] = distance[src] + wt
31 | count += 1
32 | if count == 0:
33 | break
34 |
35 | if sys.maxint in distance.values():
36 | return -1
37 |
38 | return max(distance.values())
--------------------------------------------------------------------------------
/6. Binary Trees/3. Right Side View of Tree/right-side-view-of-tree-bfs.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def rightSideView(self, root):
9 | """
10 | :type root: TreeNode
11 | :rtype: List[int]
12 | """
13 | if root == None: return []
14 | curr = root
15 | queue = []
16 | queue.append(curr)
17 | tempList = []
18 | rightNodes = []
19 | length = 1
20 | count = 0
21 | while queue != []:
22 | curr = queue[0]
23 | tempList.append(curr.val)
24 | count += 1
25 | queue = queue[1:]
26 |
27 | if curr.left:
28 | queue.append(curr.left)
29 | if curr.right:
30 | queue.append(curr.right)
31 |
32 | if length == count:
33 | rightNodes.append(tempList[-1])
34 | tempList = []
35 | count = 0
36 | length = len(queue)
37 |
38 | return rightNodes
--------------------------------------------------------------------------------
/3. Linked Lists/2. Reverse Linked Lists II - M, N Reversals/reverse-linked-lists-II-m-n-reversals.py:
--------------------------------------------------------------------------------
1 | class ListNode(object):
2 | def __init__(self, val=0, next=None):
3 | self.val = val
4 | self.next = next
5 |
6 | class Solution(object):
7 | def reverseBetween(self, head, left, right):
8 | if head == None or head.next == None:
9 | return head
10 | count = 1
11 | big_prev = None
12 | tail = None
13 | prev = None
14 | curr = head
15 | while(curr):
16 | if left <= count and count <= right:
17 | if(count == left):
18 | tail = curr
19 | temp = curr.next
20 | curr.next = prev
21 | prev = curr
22 | curr = temp
23 | if count == right:
24 | tail.next = temp
25 | if big_prev != None:
26 | big_prev.next = prev
27 | return head
28 | else:
29 | return prev
30 |
31 | else:
32 | big_prev = curr
33 | curr = curr.next
34 | count += 1
--------------------------------------------------------------------------------
/8. Graphs/2. Course Schedule/course-schedule.py:
--------------------------------------------------------------------------------
1 | class Solution(object):
2 | def canFinish(self, numCourses, prerequisites):
3 | """
4 | :type numCourses: int
5 | :type prerequisites: List[List[int]]
6 | :rtype: bool
7 | """
8 |
9 | adj_list = []
10 | inDegree = {}
11 | seen = {}
12 |
13 | for i in range(numCourses):
14 | adj_list.append([])
15 | inDegree[i] = 0
16 |
17 | for p in prerequisites:
18 | course = p[0]
19 | prereq = p[1]
20 | adj_list[prereq].append(course)
21 | inDegree[course] = inDegree[course] + 1
22 |
23 | while len(inDegree) > 0:
24 | # search for where inDegree[i] == 0
25 | count = len(inDegree)
26 | for node in inDegree:
27 | if inDegree[node] == 0:
28 | for child in adj_list[node]:
29 | inDegree[child] = inDegree[child] - 1
30 | inDegree.pop(node)
31 | break
32 | count = count - 1
33 | if count == 0:
34 | return False
35 | return True
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/1. Tree Traversals/Breadth First Search.md:
--------------------------------------------------------------------------------
1 | # Breadth First Search (BFS)
2 | Logic: start at root node → go thru nodes on same level
3 |
4 | * uses a lot of memory because
5 | * for every level @ every node, need to store the node’s children
6 | * use queue data structure to store node’s children: Space: O(n)
7 | * Downside: tree wide → queue become very large
8 | ## Code
9 | ```Python
10 | def breadthFirstSearch(self):
11 | curr = self.getRoot()
12 | orderOfNodesList = []
13 | #track children for every level
14 | queue = []
15 | #add the root to queue
16 | queue.append(curr)
17 | #while there are nodes to be seen in the tree
18 | while queue != []:
19 | #take the first node
20 | curr = queue[0]
21 | #remove it from the queue
22 | queue = queue[1:]
23 | #add the node seen to the list
24 | orderOfNodesList.append(curr.val)
25 | #check if the node has children
26 | if curr.left:
27 | queue.append(curr.left)
28 | if curr.right:
29 | queue.append(curr.right)
30 | print("bfsList: ", orderOfNodesList)
31 | return orderOfNodesList
32 | ```
--------------------------------------------------------------------------------
/6. Binary Trees/2. Level Order of a Binary Tree/level-order-of-binary-tree.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def levelOrder(self, root):
9 | """
10 | :type root: TreeNode
11 | :rtype: List[List[int]]
12 | """
13 | if root == None:
14 | return []
15 | curr = root
16 | queue = []
17 | queue.append(curr)
18 | tempList = []
19 | levelOrderOfNodes = []
20 | length = 1
21 | count = 0
22 | while queue != []:
23 | curr = queue[0]
24 | tempList.append(curr.val)
25 | count += 1
26 | queue = queue[1:]
27 |
28 | if curr.left:
29 | queue.append(curr.left)
30 | if curr.right:
31 | queue.append(curr.right)
32 |
33 | if length == count:
34 | levelOrderOfNodes.append(tempList)
35 | tempList = []
36 | count = 0
37 | length = len(queue)
38 |
39 | return levelOrderOfNodes
--------------------------------------------------------------------------------
/5. Recursion + Sortings/1. Kth Largest Element in an Array/kth-largest-element-in-an-array-optimal.py:
--------------------------------------------------------------------------------
1 | def partition(self, arr, low, high):
2 | #holds the place of where the pivot should be
3 | i = low
4 | #scans and compares #s against pivot
5 | j = low
6 | #pivot is rightmost element
7 | pivot = arr[high]
8 | while j < high:
9 | if arr[j] < arr[high]:
10 | if i != j:
11 | arr[i], arr[j] = arr[j], arr[i]
12 | i += 1
13 | j += 1
14 | else:
15 | j += 1
16 | arr[i], arr[high] = pivot, arr[i]
17 | return i
18 |
19 | def quickSelect(self, arr, low, high, k):
20 | if low < high:
21 | partition = self.partition(arr, low, high)
22 | if k == partition:
23 | return arr[k]
24 | elif k > partition:
25 | return self.quickSelect(arr, partition+1, high, k)
26 | else:
27 | return self.quickSelect(arr, low, partition-1, k)
28 | return arr[k]
29 |
30 |
31 | def findKthLargest(self, arr, k):
32 | """
33 | :type nums: List[int]
34 | :type k: int
35 | :rtype: int
36 | """
37 | indexToFind = len(arr)-k
38 | return self.quickSelect(arr, 0, len(arr)-1, indexToFind)
--------------------------------------------------------------------------------
/5. Recursion + Sortings/Learning Material/Binary Search.md:
--------------------------------------------------------------------------------
1 | # Binary Search
2 | Time: O(logn) → spend time searching thru half of array
3 | ## Iterative
4 | Space: O(1)
5 | ```
6 | def search(self, nums, target):
7 | """
8 | :type nums: List[int]
9 | :type target: int
10 | :rtype: int
11 | """
12 | left = 0
13 | right = len(nums)-1
14 | while left <= right:
15 | mid = (left+right)/2
16 | if target == nums[mid]:
17 | return mid
18 | elif target < nums[mid]:
19 | right = mid -1
20 | else:
21 | left = mid + 1
22 | return -1
23 | ```
24 | ## Recursive
25 | Space: O(n)
26 | ```
27 | def binarySearch(self, nums, left, right, target):
28 | if left <= right:
29 | mid = (right+left)/2
30 | if target == nums[mid]:
31 | return mid
32 | elif target < nums[mid]:
33 | return self.binarySearch(nums, left, mid-1, target)
34 | else:
35 | return self.binarySearch(nums, mid+1, right, target)
36 | return -1
37 |
38 | def search(self, nums, target):
39 | """
40 | :type nums: List[int]
41 | :type target: int
42 | :rtype: int
43 | """
44 | return self.binarySearch(nums, 0, len(nums)-1, target)
45 | ```
46 |
--------------------------------------------------------------------------------
/General/Tail Recursion.md:
--------------------------------------------------------------------------------
1 | ## Regular Recursion
2 | ```JavaScript
3 | function recFactorial(x) {
4 | if(x <= 1) {
5 | return 1;
6 | }
7 | return x * recFactorial(x - 1);
8 | }
9 | ```
10 |
11 | ## Call Stack Space: O(n)
12 | ```JavaScript
13 | recFactorial(4);
14 | 4 * recFactorial(3);
15 | 4 * (3 * recFactorial(2));
16 | 4 * (3 * (2 * recFactorial(1)));
17 | 4 * (3 * (2 * 1));
18 | ```
19 |
20 | * Time: O(n)
21 | * Space: O(n) because all the calls to the function must wait on an answer (have to calculate x*blah blah): `return x * recFactorial(x -1)`, for factorial 4 there were in total 4 calls to the function (4 recursive stacks)
22 |
23 | ## Tail Recursion
24 | ```JavaScript
25 | function tailFactorial(x, totalSoFar = 1) {
26 | if (x === 0) {
27 | return totalSoFar;
28 | }
29 | return tailFactorial(x - 1, totalSoFar * x);
30 | }
31 | ```
32 |
33 | ## Call Stack Space: O(1)
34 | ```JavaScript
35 | tailFactorial(4);
36 | tailFactorial(4, 1);
37 | tailFactorial(3, 4);
38 | tailFactorial(2, 12);
39 | tailFactorial(1, 24);
40 | tailFactorial(0, 24);
41 | ```
42 |
43 | * Time: O(n)
44 | * Space: O(1) because we are no longer waiting on an answer (no waiting on x * blah blah calculation): `return tailFactorial(x - 1, totalSoFar * x)`
45 | * Engine compiler dependent: tail recursion O(1) space won’t occur
46 |
--------------------------------------------------------------------------------
/6. Binary Trees/5. Validate Binary Search Tree/validate-binary-search-tree-optimal.py:
--------------------------------------------------------------------------------
1 | import sys
2 | class TreeNode(object):
3 | def __init__(self, val=0, left=None, right=None):
4 | self.val = val
5 | self.left = left
6 | self.right = right
7 |
8 | class Solution(object):
9 | def isValidBSTHelper(self, root, left, right):
10 | if root == None:
11 | return True
12 | # check that the node is within the current bounds otherwise return false
13 | if left >= root.val or root.val >= right:
14 | return False
15 | if root.left == None and root.right == None:
16 | return True
17 |
18 | leftSide = True
19 | rightSide = True
20 | if root.left != None:
21 | # if going left, update the right most value to the root value
22 | leftSide = self.isValidBSTHelper(root.left, left, root.val)
23 | if not leftSide: return False
24 | if root.right != None:
25 | rightSide = self.isValidBSTHelper(root.right, root.val, right)
26 | if not rightSide: return False
27 | return True
28 |
29 | def isValidBST(self, root):
30 | """
31 | :type root: TreeNode
32 | :rtype: bool
33 | """
34 | return self.isValidBSTHelper(root, ~sys.maxsize, sys.maxsize)
--------------------------------------------------------------------------------
/5. Recursion + Sortings/Learning Material/Insertion Sort.md:
--------------------------------------------------------------------------------
1 | # Insertion Sort
2 | ## Sort: 6 5 3 1 8 7 2 4
3 | ```
4 | Logic:
5 | * numbers are divided into sorted (left) and unsorted (right) parts.
6 | * first item in list is always considered sorted
7 | * take the first element in the unordeded part and move it from right to left
8 | ```
9 | 1 iteration thru whole array:
10 | ```
11 | 6 | 5 3 1 8 7 2 4 (swap 5 and 6)
12 | ```
13 | 2 iter:
14 | ```
15 | 5 6 | 3 1 8 7 2 4 (swap 3 and 6, swap 3 and 5)
16 | ...
17 | 3 5 6 | 1 8 7 2 4
18 | ```
19 | 8 iter:
20 | ```
21 | 1 2 3 4 5 6 7 | 8
22 | 1 2 3 4 5 6 7 8 |
23 | ```
24 | Patterns: as move down array, the extra included item is sorted among the already sorted items
25 | ## Time + Space Complexity:
26 | * Time: O(n^2)
27 | * Space: O(1)
28 | ## Best Case:
29 | List is almost or is sorted and small data sets: O(n)
30 | ## Code
31 | ```Python
32 | def insertionSort(arr):
33 | """
34 | :type arr: list
35 | :rtype: list
36 | """
37 | for i in range(1, len(arr)):
38 | j = i
39 | while j > 0:
40 | # if previous element is larger than current: like 3 2
41 | if arr[j] < arr[j-1]:
42 | # swap
43 | temp = arr[j]
44 | arr[j] = arr[j-1]
45 | arr[j-1] = temp
46 | j -= 1
47 |
48 |
49 | return arr
50 | ```
--------------------------------------------------------------------------------
/5. Recursion + Sortings/Learning Material/Selection Sort.md:
--------------------------------------------------------------------------------
1 | # Selection Sort
2 | ## Sort: 8 5 2 6 9 3 1 4 0 7
3 | ```
4 | Logic: 2 pointers
5 | * first ptr tracks the min so far and compares it with second ptr (min)
6 | * second ptr scans the rest of the list for the smallest number (scanner).
7 | * if scanner < min:
8 | min = scanner.
9 | * at end of the list, swap minimum number with the current position to be sorted.
10 | * at each iteration, next min # is placed in the right position.
11 | ```
12 | 1 iteration thru whole array:
13 | ```
14 | 8 5 2 6 9 3 1 4 0 7 (0 and 8 swap)
15 | ```
16 | 2 iter:
17 | ```
18 | 0 | 5 2 6 9 3 1 4 8 7 (1 and 5 swap)
19 | ```
20 | 8 iter:
21 | ```
22 | 1 2 3 4 5 6 7 | 8
23 | ```
24 | Patterns: At each iteration, the min # is searched and swapped with the next unsorted index
25 |
26 | ## Time + Space Complexity:
27 | * Time: O(n^2)
28 | * Space: O(1)
29 |
30 | ## Code
31 | ```Python
32 | def selectionSort(arr):
33 | """
34 | :type arr: list
35 | :rtype: list
36 | """
37 | for i in range(len(arr)-1):
38 | comparison = arr[i]
39 | temp = arr[i]
40 | index = i + 1
41 | for j in range(i + 1, len(arr)):
42 | scanner = arr[j]
43 | if scanner < comparison:
44 | comparison = scanner
45 | index = j
46 | arr[i] = comparison
47 | arr[index] = temp
48 |
49 | return arr
50 | ```
--------------------------------------------------------------------------------
/8. Graphs/1. Time Needed to Inform All Employees/time-needed-to-inform-all-employees.py:
--------------------------------------------------------------------------------
1 | class Solution(object):
2 | def numOfMinutes(self, n, headID, manager, informTime):
3 | """
4 | :type n: int
5 | :type headID: int
6 | :type manager: List[int]
7 | :type informTime: List[int]
8 | :rtype: int
9 | """
10 | max_time = 0
11 | adj_list = []
12 | seen = {}
13 | for i in range(n):
14 | adj_list.append([])
15 | seen[i] = False
16 |
17 | seen[headID] = True
18 | for emp_id in range(n):
19 | if emp_id != headID:
20 | adj_list[manager[emp_id]].append(emp_id)
21 |
22 | for neighbor in adj_list[headID]:
23 | new_time = self.dfs(neighbor, adj_list, informTime, informTime[headID], seen)
24 | max_time = max(max_time, new_time)
25 |
26 | return max_time
27 |
28 | def dfs(self, vertex, adj_list, informTime, new_time, seen):
29 | if informTime[vertex] == 0:
30 | return new_time
31 | seen[vertex] = True
32 | new_time += informTime[vertex]
33 | time = 0
34 | for neighbor in adj_list[vertex]:
35 | if not seen[neighbor]:
36 | time = max(time, self.dfs(neighbor, adj_list, informTime, new_time, seen))
37 | return time
--------------------------------------------------------------------------------
/4. Stacks + Queues/3. Implement Queues using Stacks/implement-queues-using-stacks.py:
--------------------------------------------------------------------------------
1 | from collections import deque
2 | class MyQueue(object):
3 |
4 | def __init__(self):
5 | self.elements = deque()
6 | self.save = deque()
7 |
8 | def push(self, x):
9 | """
10 | :type x: int
11 | :rtype: None
12 | """
13 | self.elements.append(x)
14 |
15 |
16 | def pop(self):
17 | """
18 | :rtype: int
19 | """
20 | while len(self.elements) > 0:
21 | self.save.append(self.elements.pop())
22 | result = self.save.pop()
23 | while len(self.save) > 0:
24 | self.elements.append(self.save.pop())
25 | return result
26 |
27 |
28 | def peek(self):
29 | """
30 | :rtype: int
31 | """
32 | while len(self.elements) > 0:
33 | self.save.append(self.elements.pop())
34 | result = self.save.pop()
35 | self.save.append(result)
36 | while len(self.save) > 0:
37 | self.elements.append(self.save.pop())
38 | return result
39 |
40 |
41 | def empty(self):
42 | """
43 | :rtype: bool
44 | """
45 | return len(self.elements) == 0
46 |
47 |
48 | # Your MyQueue object will be instantiated and called as such:
49 | # obj = MyQueue()
50 | # obj.push(x)
51 | # param_2 = obj.pop()
52 | # param_3 = obj.peek()
53 | # param_4 = obj.empty()
--------------------------------------------------------------------------------
/7. 2D Arrays/1. Number of Islands/number-of-islands.py:
--------------------------------------------------------------------------------
1 | class Solution(object):
2 | def numIslands(self, grid):
3 | """
4 | :type grid: List[List[str]]
5 | :rtype: int
6 | """
7 | num_of_islands = 0
8 | queue = []
9 | # Perform sequential search to find 1's, and pass row + col into bfs
10 | for row in range(len(grid)):
11 | for col in range(len(grid[0])):
12 | if grid[row][col] == "1":
13 | queue.append([row, col])
14 | self.bfs(grid, queue)
15 | num_of_islands += 1
16 | queue = []
17 | return num_of_islands
18 |
19 | def bfs(self, grid, queue):
20 | # up right down left
21 | directions = [[-1, 0], [0, 1], [1, 0], [0, -1]]
22 |
23 | while queue != []:
24 | row = queue[0][0]
25 | col = queue[0][1]
26 | grid[row][col] = "2"
27 | queue = queue[1:]
28 | for direction in directions:
29 | row1 = row + direction[0]
30 | col1 = col + direction[1]
31 | # check if the direction is out of bounds or visited
32 | if row1 < 0 or row1 >= len(grid) or col1 < 0 or col1 >= len(grid[0]) or grid[row1][col1] == "0" or grid[row1][col1] == "2":
33 | continue
34 | else:
35 | grid[row1][col1] = "2"
36 | queue.append([row1, col1])
--------------------------------------------------------------------------------
/5. Recursion + Sortings/Learning Material/Bubble Sort.md:
--------------------------------------------------------------------------------
1 | # Bubble Sort
2 | ## Sort: 6 5 3 1 8 7 2 4
3 | ```
4 | Logic: sliding window between 2 elements (swap if curr < prev)
5 | while list not sorted:
6 | if prev element < curr element:
7 | move sliding window
8 | else:
9 | swap prev and curr elements
10 | ```
11 | ## Example:
12 | 1 iteration thru whole array:
13 | ```
14 | 6 5 3 1 8 7 2 4 (swap 6 and 5)
15 | 5 6 3 1 8 7 2 4 (swap 6 and 3)
16 | 5 3 6 1 8 7 2 4 (swap 6 and 1)
17 | 5 3 1 6 8 7 2 4 (keep 6 and 8)
18 | 5 3 1 6 8 7 2 4 (swap 8 and 7)
19 | 5 3 1 6 7 8 2 4 (swap 8 and 2)
20 | 5 3 1 6 7 2 8 4 (swap 8 and 4)
21 | 5 3 1 6 7 2 4 | 8 (8 is correctly sorted)
22 | ```
23 | 2 iter:
24 | ```
25 | ...
26 | 3 1 5 6 2 4 | 7 8 (7 is correctly sorted)
27 | ...
28 | 8 iter:
29 | | 1 2 3 4 5 6 7 8 (1 is correctly sorted)
30 | ```
31 | Patterns: The highest unsorted number (highest number not at end of array) will be continuously swapped until it reaches the end.
32 | ## Time + Space Complexity:
33 | * Time: O(n^2)
34 | * Space: O(1)
35 | ## Best Case:
36 | O(n): continuously comparing between 2 elements
37 | Code
38 | ```Python
39 | def bubbleSort(arr):
40 | """
41 | :type arr: list
42 | :rtype: list
43 | """
44 | bubble = len(arr)
45 | for i in range(bubble-1):
46 | for j in range(0, bubble-1):
47 | # j and j + 1
48 | if arr[j] > arr[j+1]:
49 | # swap them
50 | temp = arr[j]
51 | arr[j] = arr[j+1]
52 | arr[j+1] = temp
53 | bubble -= 1
54 | return arr
55 | ```
--------------------------------------------------------------------------------
/7. 2D Arrays/2. Rotting Oranges/rotting-oranges.py:
--------------------------------------------------------------------------------
1 | class Solution(object):
2 | def orangesRotting(self, grid):
3 | """
4 | :type grid: List[List[int]]
5 | :rtype: int
6 | """
7 |
8 | directions = [[-1, 0], [0, 1], [1, 0], [0, -1]]
9 | queue = []
10 | num_of_min = 0
11 | size = 0
12 | num_of_fresh_oranges = 0
13 | for row in range(len(grid)):
14 | for col in range(len(grid[0])):
15 | if grid[row][col] == 2:
16 | queue.append([row, col])
17 | size += 1
18 | elif grid[row][col] == 1:
19 | num_of_fresh_oranges += 1
20 |
21 | while queue != []:
22 | row = queue[0][0]
23 | col = queue[0][1]
24 | queue = queue[1:]
25 | size -= 1
26 | for direction in directions:
27 | row1 = row + direction[0]
28 | col1 = col + direction[1]
29 | if row1 < 0 or row1 >= len(grid) or col1 < 0 or col1 >= len(grid[0]) or grid[row1][col1] != 1:
30 | continue
31 | else:
32 | grid[row1][col1] = 2
33 | num_of_fresh_oranges -= 1
34 | queue.append([row1, col1])
35 | if size == 0:
36 | num_of_min += 1
37 | size = len(queue)
38 |
39 |
40 | if num_of_fresh_oranges > 0:
41 | return -1
42 |
43 | if num_of_min == 0:
44 | return 0
45 | return num_of_min - 1
--------------------------------------------------------------------------------
/6. Binary Trees/4. Count Complete Tree Nodes/count-complete-tree-nodes-optimal.py:
--------------------------------------------------------------------------------
1 | class TreeNode(object):
2 | def __init__(self, val=0, left=None, right=None):
3 | self.val = val
4 | self.left = left
5 | self.right = right
6 |
7 | class Solution(object):
8 | def maxHeight(self, root):
9 | if root == None:
10 | return 0
11 | leftHeight = 1 + self.maxHeight(root.left)
12 | rightHeight = 1 + self.maxHeight(root.right)
13 | return max(leftHeight, rightHeight)
14 |
15 | def countNodesHelper(self, root, h, currHeight, numNodes):
16 | if root == None:
17 | return numNodes
18 |
19 | if root.left == None:
20 | numNodes += 1
21 | return numNodes
22 | else:
23 | left = self.maxHeight(root.left)
24 | right = self.maxHeight(root.right)
25 | if right >= left:
26 | numNodes += pow(2, h-1-currHeight)
27 | currHeight+=1
28 | return self.countNodesHelper(root.right, h, currHeight, numNodes)
29 | else:
30 | currHeight+=1
31 | return self.countNodesHelper(root.left, h, currHeight, numNodes)
32 |
33 |
34 | def countNodes(self, root):
35 | """
36 | :type root: TreeNode
37 | :rtype: int
38 | """
39 | if root == None:
40 | return 0
41 | h = self.maxHeight(root)
42 | numNodes = pow(2, h-1)-1
43 | currHeight = 1
44 | numNodes = self.countNodesHelper(root, h, currHeight, numNodes)
45 | return numNodes
46 |
--------------------------------------------------------------------------------
/2. Strings/1. Backspace String Compare/backspace-string-compare-optimal.py:
--------------------------------------------------------------------------------
1 | def backspaceCompare(self, s, t):
2 | """
3 | :type s: str
4 | :type t: str
5 | :rtype: bool
6 | """
7 | p1 = len(s) - 1
8 | p2 = len(t) - 1
9 | stepS = 0
10 | stepT = 0
11 |
12 | while p1 >= 0 or p2 >= 0:
13 | #as long as p1 is not negative
14 | while p1 >= 0:
15 | #if find # then move on to the next char, and increase stepS
16 | if s[p1] == "#":
17 | p1 -= 1
18 | stepS +=1
19 | #if there are stepS (chars to skip) then move on to next char and decrease the number of stepS to skip
20 | elif stepS > 0:
21 | p1 -= 1
22 | stepS -= 1
23 | #if there are no chars to skip, (no #'s or no chars before #'s), then break
24 | else:
25 | break
26 |
27 | while p2 >= 0:
28 | if t[p2] == "#":
29 | p2 -= 1
30 | stepT +=1
31 | elif stepT > 0:
32 | p2 -= 1
33 | stepT -= 1
34 | else:
35 | break
36 |
37 | #if both indices are negative, then return true
38 | #if both indices ended but one is negative and the other is not, then return false
39 | if p1 < 0: return p2 < 0
40 | if p2 < 0: return p1 < 0
41 | #if the chars are not #'s or chars before #'s and do not equal each other, return false
42 | if s[p1] != t[p2]: return False
43 | #if the characters are equal, then check the rest of the string
44 | p1 -= 1
45 | p2 -= 1
46 |
47 | return True
--------------------------------------------------------------------------------
/5. Recursion + Sortings/2. Find First and Last Position of Element in Sorted Array/find-first-and-last-position-of-element-in-sorted-array-recursive.py:
--------------------------------------------------------------------------------
1 | def binarySearch(self, nums, left, right, target, ranges, prevMid):
2 | if left <= right:
3 | mid = (right+left)/2
4 | if target == nums[mid]:
5 | if mid < ranges[0] or ranges[0] == -1:
6 | ranges[0] = mid
7 | if ranges[1] < mid:
8 | ranges[1] = mid
9 |
10 | if prevMid != -1:
11 | #right
12 | if prevMid < mid:
13 | return self.binarySearch(nums, mid+1, right, target, ranges, mid)
14 | else:
15 | return self.binarySearch(nums, left, mid-1, target, ranges, mid)
16 | else:
17 | self.binarySearch(nums, left, mid-1, target, ranges, mid)
18 | self.binarySearch(nums, mid+1, right, target, ranges, mid)
19 |
20 | elif target < nums[mid]:
21 | return self.binarySearch(nums, left, mid-1, target, ranges, prevMid)
22 | else:
23 | return self.binarySearch(nums, mid+1, right, target, ranges, prevMid)
24 | return ranges
25 | def searchRange(self, nums, target):
26 | """
27 | :type nums: List[int]
28 | :type target: int
29 | :rtype: List[int]
30 | """
31 | prevMid = -1
32 | ranges = [-1, -1]
33 |
34 | if nums == []:
35 | return ranges
36 | if len(nums) == 1:
37 | if nums[0] == target:
38 | return [0, 0]
39 | else:
40 | ranges
41 | if target < nums[0] or nums[-1] < target:
42 | return ranges
43 |
44 | return self.binarySearch(nums, 0, len(nums)-1,target, ranges, prevMid)
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/1. Tree Traversals/Binary Tree Class Code.py:
--------------------------------------------------------------------------------
1 | class Node:
2 | def __init__(self, val):
3 | self.left = None
4 | self.right= None
5 | self.val = val
6 |
7 | class Tree:
8 | def __init__(self):
9 | self.root = None
10 |
11 | def getRoot(self):
12 | return self.root
13 |
14 | def add(self, val):
15 | if self.root is None:
16 | self.root = Node(val)
17 | else:
18 | self._add(val, self.root)
19 |
20 | def _add(self, val, node):
21 | if val < node.val:
22 | if node.left is not None:
23 | self._add(val, node.left)
24 | else:
25 | node.left = Node(val)
26 | else:
27 | if node.right is not None:
28 | self._add(val, node.right)
29 | else:
30 | node.right = Node(val)
31 |
32 | def find(self, val):
33 | if self.root is not None:
34 | return self._find(val, self.root)
35 | else:
36 | return None
37 |
38 | def _find(self, val, node):
39 | if val == node.val:
40 | return node
41 | elif (val < node.val and node.left is not None):
42 | return self._find(val, node.left)
43 | elif (val > node.val and node.right is not None):
44 | return self._find(val, node.r)
45 |
46 | def deleteTree(self):
47 | # garbage collector will do this for us.
48 | self.root = None
49 |
50 | def printTree(self):
51 | if self.root is not None:
52 | self._printTree(self.root)
53 |
54 | def _printTree(self, node):
55 | if node is not None:
56 | self._printTree(node.left)
57 | print(str(node.val) + ' ')
58 | self._printTree(node.right)
59 |
60 | tree = Tree()
61 | tree.add(9)
62 | tree.add(4)
63 | tree.add(6)
64 | tree.add(20)
65 | tree.add(170)
66 | tree.add(15)
67 | tree.add(1)
68 | tree.printTree()
69 | # print(tree.find(3).val)
70 | # print(tree.find(10))
71 | # tree.deleteTree()
72 | # tree.printTree()
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/2. Heaps - Priority Queues/Insertion (Sift Up).md:
--------------------------------------------------------------------------------
1 | # Insertion (Sift Up)
2 | ## Conceptual
3 | ### Max Heap
4 | ```
5 | 50
6 | 40 25
7 | 20 35 10 15
8 | ```
9 | **Insert: 45**
10 | Insert new value into the most left position (b/c heap is complete binary tree)
11 | ```
12 | 50
13 | 40 25
14 | 20 35 10 15
15 | 45
16 | ```
17 | * Keep comparing new node (45) to parent
18 | * **20 < 45**
19 | * **Swap**
20 | ```
21 | 50
22 | 40 25
23 | 45 35 10 15
24 | 20
25 | ```
26 | * **40 < 45**
27 | * **Swap**
28 | ```
29 | 50
30 | 45 25
31 | 40 35 10 15
32 | 20
33 | ```
34 | * **50 > 45**
35 | * Stop
36 |
37 |
38 | ### Min Heap
39 | Instead of swapping when new node is larger than parent node,
40 | swap when NEW node is SMALLER than PARENT
41 |
42 | ## Array Implementation
43 | ```
44 | [50, 40, 25, 20, 35, 10, 15, 45]
45 | 0 1 2 3 4 5 6 7
46 | ```
47 | * parent of 45’s index = floor((idx - 1) / 2 ) = floor((8 - 1) / 2) = 3
48 | → swap 20 and 45
49 | * parent of 45’s index = floor((idx - 1) / 2 ) = floor((3 - 1) / 2) = 1
50 | → swap 40 and 45
51 | * parent of 45’s index = floor((idx - 1) / 2 ) = floor((1 - 1) / 2) = 0
52 | → no swap (50 is larger)
53 |
54 | ## Code
55 | ```Python
56 | def push(self, val):
57 | self.heap.append(val) # add new val to bottom of heap
58 | self.siftUp() # sift new val up
59 | return self.size()
60 |
61 | def siftUp(self):
62 | nodeIdx = self.size() - 1
63 | parent = self.parent(nodeIdx)
64 | # MAX heap: while the parent is smaller -> sift up: parent < node
65 | # MIN heap: while the parent is larger -> sift up: parent > node
66 | while(nodeIdx > 0 and self.compare(parent, nodeIdx)):
67 | # switch the parent and current node value
68 | self.swap(self.parent(nodeIdx), nodeIdx)
69 | # move node ptr to parent index
70 | nodeIdx = self.parent(nodeIdx)
71 | parent = self.parent(nodeIdx)
72 |
73 | def parent(self, idx):
74 | return math.floor((idx - 1) / 2)
75 |
76 | def compare(self, i, j):
77 | return self.comparator(self.heap[i], self.heap[j]);
78 |
79 | def swap(self, i, j):
80 | temp = self.heap[i];
81 | self.heap[i] = self.heap[j];
82 | self.heap[j] = temp;
83 | ```
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/2. Heaps - Priority Queues/Priority Queue.py:
--------------------------------------------------------------------------------
1 | import math
2 | class PriorityQueue:
3 | def __init__(self, comparator):
4 | self.heap = []
5 | self.comparator = comparator
6 |
7 | def size(self):
8 | return len(self.heap)
9 |
10 | def isEmpty(self):
11 | return self.size() == 0
12 |
13 | def peek(self):
14 | if not self.isEmpty():
15 | return self.heap[0]
16 | return None
17 |
18 | def push(self, val):
19 | self.heap.append(val) # add new val to bottom of heap
20 | self.siftUp() # sift new val up
21 | return self.size()
22 |
23 | def siftUp(self):
24 | nodeIdx = self.size() - 1
25 | parent = self.parent(nodeIdx)
26 | # MAX heap: while the parent is smaller -> sift up: parent < node
27 | # MIN heap: while the parent is larger -> sift up: parent > node
28 | while(nodeIdx > 0 and self.compare(parent, nodeIdx)):
29 | # switch the parent and current node value
30 | self.swap(self.parent(nodeIdx), nodeIdx)
31 | # move node ptr to parent index
32 | nodeIdx = self.parent(nodeIdx)
33 | parent = self.parent(nodeIdx)
34 |
35 | def pop(self):
36 | top = self.heap[0] # save the min/max value
37 | # put the last element into the top position
38 | self.heap[0] = self.heap[self.size() - 1]
39 | # remove the repeat element from the last position
40 | self.heap.pop(self.size() - 1)
41 | # sift the new top value down to get the new min/max
42 | self.siftDown()
43 | return top # return the original min/max value
44 |
45 | def siftDown(self):
46 | nodeIdx = 0
47 | while nodeIdx < self.size():
48 | # choose min/max b/w left and right child
49 | childIdx = self.siftDownCompare(nodeIdx)
50 | # compare nodeIdx with the min/max child
51 | if childIdx != -1 and self.compare(nodeIdx, childIdx):
52 | # swap if
53 | # MAX: node < child -> child larger so should be on top
54 | # MIN: node > child -> child smaller so should be on top
55 | self.swap(nodeIdx, childIdx)
56 | nodeIdx = childIdx
57 | else:
58 | break
59 |
60 | def parent(self, idx):
61 | return math.floor((idx - 1) / 2)
62 |
63 | def leftChild(self, idx):
64 | return 2 * idx + 1
65 |
66 | def rightChild(self, idx):
67 | return 2 * idx + 2
68 |
69 | def swap(self, i, j):
70 | temp = self.heap[i];
71 | self.heap[i] = self.heap[j];
72 | self.heap[j] = temp;
73 |
74 | def compare(self, i, j):
75 | return self.comparator(self.heap[i], self.heap[j]);
76 |
77 | def siftDownCompare(self, idx):
78 | isMax = self.comparator(1, 2)
79 | leftChildIdx = self.leftChild(idx)
80 | rightChildIdx = self.rightChild(idx)
81 | if leftChildIdx >= self.size():
82 | return -1
83 | elif leftChildIdx < self.size() and rightChildIdx >= self.size():
84 | return leftChildIdx
85 | elif rightChildIdx < self.size() and leftChildIdx >= self.size():
86 | return rightChildIdx
87 | if isMax:
88 | if self.heap[leftChildIdx] > self.heap[rightChildIdx]:
89 | return leftChildIdx
90 | else:
91 | return rightChildIdx
92 | else:
93 | if self.heap[leftChildIdx] < self.heap[rightChildIdx]:
94 | return leftChildIdx
95 | else:
96 | return rightChildIdx
97 | # MAX heap: swap node w/ max(left child, right child)
98 | # MIN heap: swap node w/ min(left child, right child)
99 |
100 | def printHeap(self):
101 | if self.heap is not None:
102 | for i in range(len(self.heap)):
103 | print(i, " element: ", self.heap[i], " ")
104 |
105 | def maxComparator(a, b):
106 | return a < b
107 | def minComparator(a, b):
108 | return a > b
109 |
110 | heap = PriorityQueue(maxComparator)
111 | heap.push(50)
112 | heap.push(40)
113 | heap.push(25)
114 | heap.push(20)
115 | heap.push(35)
116 | heap.push(10)
117 | heap.push(15)
118 | heap.push(45)
119 | heap.pop()
120 | heap.printHeap()
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/2. Heaps - Priority Queues/Deletion (Sift Down).md:
--------------------------------------------------------------------------------
1 | # Deletion (Sift Down)
2 | ## Conceptual
3 | ### Max Heap
4 | * Removal deletion, retrieval, return root value (greatest value)
5 | * Restructure heap so max value at root and so tree is complete binary tree
6 | * Take last node and place it in the root node and sift value down
7 | ## Example
8 | ```
9 | 75
10 | 50 25
11 | 45 35 10 15
12 | 20 40
13 | ```
14 | * save 75 into variable, then get rid of 40
15 | * swap 75 and 40 variable
16 | * set 45’s right child to null
17 | ```
18 | 40
19 | 50 25
20 | 45 35 10 15
21 | 20
22 | ```
23 | * max(left child, right child) = max(50, 25) = 50
24 | * 50 > 40
25 | * swap 50 and 40
26 | ```
27 | 50
28 | 40 25
29 | 45 35 10 15
30 | 20
31 | ```
32 | * max(left child, right child) = max(45, 35) = 45
33 | * 45 > 40
34 | * swap 45 and 40
35 | ```
36 | 50
37 | 45 25
38 | 40 35 10 15
39 | 20
40 | ```
41 | * max(left child, null) = 20
42 | * 20 < 40
43 | * stop
44 | ### Min Heap
45 | * instead of max use mix()
46 | * swap only if child less than parent
47 | ## Array Implementation
48 | ```
49 | [75, 50, 25, 45, 35, 10, 15, 20, 40]
50 | 0 1 2 3 4 5 6 7 8
51 |
52 | 75
53 | 50 25
54 | 45 35 10 15
55 | 20 40
56 | ```
57 | * save 75 into variable, then get rid of 40 return_value = heap[0]
58 | * swap 75 and 40 variable
59 | * set 45’s right child to null
60 | ```
61 | [40, 50, 25, 45, 35, 10, 15, 20]
62 | 0 1 2 3 4 5 6 7
63 |
64 | 40
65 | 50 25
66 | 45 35 10 15
67 | 20
68 |
69 | left child idx = 2*idx + 1 = 0 + 1 = 1
70 | right child idx = 2*idx + 2 = 2
71 | max(left child, right child) = max(50, 25) = 50
72 | ```
73 | * 50 > 40
74 | * swap 50 and 40
75 | ```
76 | [50, 40, 25, 45, 35, 10, 15, 20]
77 | 0 1 2 3 4 5 6 7
78 |
79 | 50
80 | 40 25
81 | 45 35 10 15
82 | 20
83 | ```
84 | ... and so on
85 | ## Code
86 | ```Python
87 | def pop(self):
88 | top = self.heap[0] # save the min/max value
89 | # put the last element into the top position
90 | self.heap[0] = self.heap[self.size() - 1]
91 | # remove the repeat element from the last position
92 | self.heap.pop(self.size() - 1)
93 | # sift the new top value down to get the new min/max
94 | self.siftDown()
95 | return top # return the original min/max value
96 |
97 | def siftDown(self):
98 | nodeIdx = 0
99 | while nodeIdx < self.size():
100 | # choose min/max b/w left and right child
101 | childIdx = self.siftDownCompare(nodeIdx)
102 | # compare nodeIdx with the min/max child
103 | if childIdx != -1 and self.compare(nodeIdx, childIdx):
104 | # swap if
105 | # MAX: node < child -> child larger so should be on top
106 | # MIN: node > child -> child smaller so should be on top
107 | self.swap(nodeIdx, childIdx)
108 | nodeIdx = childIdx
109 | else:
110 | break
111 |
112 | def siftDownCompare(self, idx):
113 | isMax = self.comparator(1, 2)
114 | leftChildIdx = self.leftChild(idx)
115 | rightChildIdx = self.rightChild(idx)
116 | if leftChildIdx >= self.size():
117 | return -1
118 | elif leftChildIdx < self.size() and rightChildIdx >= self.size():
119 | return leftChildIdx
120 | elif rightChildIdx < self.size() and leftChildIdx >= self.size():
121 | return rightChildIdx
122 | if isMax:
123 | if self.heap[leftChildIdx] > self.heap[rightChildIdx]:
124 | return leftChildIdx
125 | else:
126 | return rightChildIdx
127 | else:
128 | if self.heap[leftChildIdx] < self.heap[rightChildIdx]:
129 | return leftChildIdx
130 | else:
131 | return rightChildIdx
132 | # MAX heap: swap node w/ max(left child, right child)
133 | # MIN heap: swap node w/ min(left child, right child)
134 |
135 | def leftChild(self, idx):
136 | return 2 * idx + 1
137 |
138 | def rightChild(self, idx):
139 | return 2 * idx + 2
140 |
141 | def swap(self, i, j):
142 | temp = self.heap[i];
143 | self.heap[i] = self.heap[j];
144 | self.heap[j] = temp;
145 |
146 | def compare(self, i, j):
147 | return self.comparator(self.heap[i], self.heap[j]);
148 | ```
--------------------------------------------------------------------------------
/6. Binary Trees/Learning Material/2. Heaps - Priority Queues/Heaps.md:
--------------------------------------------------------------------------------
1 | # Heaps / Priority Queues
2 | ## About
3 | ### What are heaps?
4 | * data structure that represents a COMPLETE (2nd to last level is full) binary tree
5 | * max heap: root larger than children nodes in tree (rest of children nodes not in max order)
6 | * min heap: root smallest than children nodes in tree (rest of children nodes not in min order)
7 |
8 | ### Indices
9 | * parent: floor((idx-1) / 2)
10 | * left child: 2*idx + 1
11 | * right child: 2*idx + 2
12 |
13 | ### Time Complexity
14 | * Creation: O(n)
15 | * Insertion: O(logn) [base → root (height of tree → logn)]
16 | * Deletion: O(logn) [root → base (height of tree → logn)]
17 |
18 | ### Important Methods
19 | * Insertion (Sift Up)
20 | * Deletion (Sift Down)
21 |
22 | ## Code (Max Heap)
23 | ```Python
24 | import math
25 | class PriorityQueue:
26 | def __init__(self, comparator):
27 | self.heap = []
28 | self.comparator = comparator
29 |
30 | def size(self):
31 | return len(self.heap)
32 |
33 | def isEmpty(self):
34 | return self.size() == 0
35 |
36 | def peek(self):
37 | if not self.isEmpty():
38 | return self.heap[0]
39 | return None
40 |
41 | def push(self, val):
42 | self.heap.append(val) # add new val to bottom of heap
43 | self.siftUp() # sift new val up
44 | return self.size()
45 |
46 | def siftUp(self):
47 | nodeIdx = self.size() - 1
48 | parent = self.parent(nodeIdx)
49 | # MAX heap: while the parent is smaller -> sift up: parent < node
50 | # MIN heap: while the parent is larger -> sift up: parent > node
51 | while(nodeIdx > 0 and self.compare(parent, nodeIdx)):
52 | # switch the parent and current node value
53 | self.swap(self.parent(nodeIdx), nodeIdx)
54 | # move node ptr to parent index
55 | nodeIdx = self.parent(nodeIdx)
56 | parent = self.parent(nodeIdx)
57 |
58 | def pop(self):
59 | top = self.heap[0] # save the min/max value
60 | # put the last element into the top position
61 | self.heap[0] = self.heap[self.size() - 1]
62 | # remove the repeat element from the last position
63 | self.heap.pop(self.size() - 1)
64 | # sift the new top value down to get the new min/max
65 | self.siftDown()
66 | return top # return the original min/max value
67 |
68 | def siftDown(self):
69 | nodeIdx = 0
70 | while nodeIdx < self.size():
71 | # choose min/max b/w left and right child
72 | childIdx = self.siftDownCompare(nodeIdx)
73 | # compare nodeIdx with the min/max child
74 | if childIdx != -1 and self.compare(nodeIdx, childIdx):
75 | # swap if
76 | # MAX: node < child -> child larger so should be on top
77 | # MIN: node > child -> child smaller so should be on top
78 | self.swap(nodeIdx, childIdx)
79 | nodeIdx = childIdx
80 | else:
81 | break
82 |
83 | def parent(self, idx):
84 | return math.floor((idx - 1) / 2)
85 |
86 | def leftChild(self, idx):
87 | return 2 * idx + 1
88 |
89 | def rightChild(self, idx):
90 | return 2 * idx + 2
91 |
92 | def swap(self, i, j):
93 | temp = self.heap[i];
94 | self.heap[i] = self.heap[j];
95 | self.heap[j] = temp;
96 |
97 | def compare(self, i, j):
98 | return self.comparator(self.heap[i], self.heap[j]);
99 |
100 | def siftDownCompare(self, idx):
101 | isMax = self.comparator(1, 2)
102 | leftChildIdx = self.leftChild(idx)
103 | rightChildIdx = self.rightChild(idx)
104 | if leftChildIdx >= self.size():
105 | return -1
106 | elif leftChildIdx < self.size() and rightChildIdx >= self.size():
107 | return leftChildIdx
108 | elif rightChildIdx < self.size() and leftChildIdx >= self.size():
109 | return rightChildIdx
110 | if isMax:
111 | if self.heap[leftChildIdx] > self.heap[rightChildIdx]:
112 | return leftChildIdx
113 | else:
114 | return rightChildIdx
115 | else:
116 | if self.heap[leftChildIdx] < self.heap[rightChildIdx]:
117 | return leftChildIdx
118 | else:
119 | return rightChildIdx
120 | # MAX heap: swap node w/ max(left child, right child)
121 | # MIN heap: swap node w/ min(left child, right child)
122 |
123 | def printHeap(self):
124 | if self.heap is not None:
125 | for i in range(len(self.heap)):
126 | print(i, " element: ", self.heap[i], " ")
127 |
128 | def maxComparator(a, b):
129 | return a < b
130 | def minComparator(a, b):
131 | return a > b
132 |
133 | heap = PriorityQueue(maxComparator)
134 | heap.push(50)
135 | heap.push(40)
136 | heap.push(25)
137 | heap.push(20)
138 | heap.push(35)
139 | heap.push(10)
140 | heap.push(15)
141 | heap.push(45)
142 | heap.pop()
143 | heap.printHeap()
144 | ```
145 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Master the Coding Interview: Big Tech (FAANG) Interviews
2 | This repository contains step by step processes and Python solutions to the LeetCode problems reviewed in [Zero To Mastery](https://zerotomastery.io/)'s Udemy course [Master the Coding Interview: Big Tech (FAANG) Interviews](https://www.udemy.com/share/103J2K3@qe9lgUOC5jQCWRWTmPywBQSm1RqY-0fV8O-u23o5D34spyB7ZPocOVDee9aeSwy1/).
3 |
4 | Throughout this repo are some Data Strucutres and Algorithms review notes and coding interview techniques. Check out [this repository](https://github.com/sandhya-veludandi/tech-flashcards) to review Data Structures and Algorithms flashcards.
5 |
6 | | Status | Category | Problem | Difficulty | Solution Folder |
7 | | ------ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
8 | | ✅ | Arrays | [Two Sum](https://leetcode.com/problems/two-sum/) | Easy | [Two Sum Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/1.%20Arrays/1.%20Two%20Sum) |
9 | | ✅ | Arrays | [Container with Most Water](https://leetcode.com/problems/container-with-most-water/) | Medium | [Container with Most Water Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/1.%20Arrays/2.%20Container%20with%20Most%20Water) |
10 | | ✅ | Arrays | [Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/) | Hard | [Trapping Rain Water Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/1.%20Arrays/3.%20Trapping%20Rain%20Water) |
11 | | ✅ | Strings | [Backspace String Compare](https://leetcode.com/problems/backspace-string-compare/) | Easy | [Backspace String Compare Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/2.%20Strings/1.%20Backspace%20String%20Compare) |
12 | | ✅ | Strings | [Longest Substring without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Medium | [Longest Substring without Repeating Characters Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/2.%20Strings/2.%20Longest%20Substring%20without%20Repeating%20Characters) |
13 | | ✅ | Strings | [Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | Easy | [Valid Palindrome Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/2.%20Strings/3.%20Valid%20Palindrome) |
14 | | ✅ | Strings | [Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) | Easy | [Valid Palindrome II Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/2.%20Strings/4.%20Valid%20Palindrome%20II%20-%20Almost%20Palindrome) |
15 | | ✅ | Linked Lists | [Reverse a Linked List](https://leetcode.com/problems/reverse-linked-list/) | Easy | [Reverse a Linked List Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/3.%20Linked%20Lists/1.%20Reverse%20a%20Linked%20List) |
16 | | ✅ | Linked Lists | [Reverse a Linked List II](https://leetcode.com/problems/reverse-linked-list-ii/) | Medium | [Reverse a Linked List II Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/3.%20Linked%20Lists/2.%20Reverse%20Linked%20Lists%20II%20-%20M%2C%20N%20Reversals) |
17 | | ✅ | Linked Lists | [Flatten a Multilevel Doubly Linked List](https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/) | Medium | [Flatten a Multilevel Doubly Linked List Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/3.%20Linked%20Lists/3.%20Merge%20a%20Multi-level%20Doubly%20Linked%20List) |
18 | | ✅ | Linked Lists | [Linked List Cycle I](https://leetcode.com/problems/linked-list-cycle/) | Easy | [Linked List Cycle I Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/3.%20Linked%20Lists/4.%20Linked%20List%20Cycle%20(I%20and%20II)) |
19 | | ✅ | Linked Lists | [Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/) | Medium | [Linked List Cycle II Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/3.%20Linked%20Lists/4.%20Linked%20List%20Cycle%20(I%20and%20II)) |
20 | | ✅ | Stacks + Queues | [Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | Easy | [Valid Parentheses Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/4.%20Stacks%20%2B%20Queues/1.%20Valid%20Parentheses) |
21 | | ✅ | Stacks + Queues | [Minimum Remove to Make Valid Parentheses](https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/) | Medium | [Minimum Remove to Make Valid Parentheses Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/4.%20Stacks%20%2B%20Queues/2.%20Minimum%20Remove%20to%20Make%20Valid%20Parentheses) |
22 | | ✅ | Stacks + Queues | [Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/) | Easy | [Implement Queue using Stacks Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/4.%20Stacks%20%2B%20Queues/3.%20Implement%20Queues%20using%20Stacks) |
23 | | ✅ | Recursion + Sortings | [Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) | Medium | [Kth Largest Element in an Array Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/5.%20Recursion%20%2B%20Sortings/1.%20Kth%20Largest%20Element%20in%20an%20Array) |
24 | | ✅ | Recursion + Sortings | [Find First and Last Position of Element in Sorted Array](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | Medium | [Find First and Last Position of Element in Sorted Array Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/5.%20Recursion%20%2B%20Sortings/2.%20Find%20First%20and%20Last%20Position%20of%20Element%20in%20Sorted%20Array) |
25 | | ✅ | Binary Trees | [Maximum Depth of a Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | Easy | [Maximum Depth of a Binary Tree Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/6.%20Binary%20Trees/1.%20Maximum%20Depth%20of%20a%20Binary%20Tree) |
26 | | ✅ | Binary Trees | [Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Medium | [Binary Tree Level Order Traversal Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/6.%20Binary%20Trees/2.%20Level%20Order%20of%20a%20Binary%20Tree) |
27 | | ✅ | Binary Trees | [Binary Tree Right Side View](https://leetcode.com/problems/binary-tree-right-side-view/) | Medium | [Binary Tree Right Side View Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/6.%20Binary%20Trees/3.%20Right%20Side%20View%20of%20Tree) |
28 | | ✅ | Binary Trees | [Count Complete Tree Nodes](https://leetcode.com/problems/count-complete-tree-nodes/) | Medium | [Count Complete Tree Nodes Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/6.%20Binary%20Trees/4.%20Count%20Complete%20Tree%20Nodes) |
29 | | ✅ | Binary Trees | [Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) | Medium | [Validate Binary Search Tree Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/6.%20Binary%20Trees/5.%20Validate%20Binary%20Search%20Tree) |
30 | | ✅ | 2D Arrays | [Number of Islands](https://leetcode.com/problems/number-of-islands/) | Medium | [Number of Islands Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/7.%202D%20Arrays/1.%20Number%20of%20Islands) |
31 | | ✅ | 2D Arrays | [Rotting Oranges](https://leetcode.com/problems/rotting-oranges/) | Medium | [Rotting Oranges Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/7.%202D%20Arrays/2.%20Rotting%20Oranges) |
32 | | ✅ | 2D Arrays | [LC Walls and Gates](https://leetcode.com/problems/walls-and-gates/) or [Coding Ninjas Walls and Gates](https://www.codingninjas.com/codestudio/problems/walls-and-gates_1092887) | Medium | [Walls and Gates Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/7.%202D%20Arrays/3.%20Walls%20and%20Gates) |
33 | | ✅ | Graphs | [Time Needed to Inform All Employees](https://leetcode.com/problems/time-needed-to-inform-all-employees/) | Medium | [Time Needed to Inform All Employees Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/8.%20Graphs/1.%20Time%20Needed%20to%20Inform%20All%20Employees) |
34 | | ✅ | Graphs | [Course Schedule](https://leetcode.com/problems/course-schedule/) | Medium | [Course Schedule Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/8.%20Graphs/2.%20Course%20Schedule) |
35 | | ✅ | Graphs | [Network Delay Time](https://leetcode.com/problems/network-delay-time/) | Medium | [Network Delay Time Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/8.%20Graphs/3.%20Network%20Delay%20Time) |
36 | | ✅ | Dynamic Programming | [Min Cost Climbing Stairs](https://leetcode.com/problems/min-cost-climbing-stairs/) | Easy | [Min Cost Climbing Stairs Solution](https://github.com/sandhya-veludandi/master-the-coding-interview/tree/main/9.%20Dynamic%20Programming/1.%20Staircase) |
37 | | ⚒️ | Dynamic Programming | [Knight Probability in Chessboard](https://leetcode.com/problems/knight-probability-in-chessboard/) | Medium | in progress |
38 | | ⚒️ | Backtracking | [Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) | Hard | in progress |
39 | | ⚒️ | Interface Design | Monarchy | None | in progress |
40 | | ⚒️ | Tries | [Implement Prefix Trie](https://leetcode.com/problems/implement-trie-prefix-tree/) | Medium | in progress |
41 |
--------------------------------------------------------------------------------