100 DSA Python
100 DSA Python
By: coding_error1
1. Two Sum
2. Best Time to Buy and Sell Stock
3. Contains Duplicate
4. Maximum Subarray (Kadane’s Algo)
5. Move Zeroes
6. Rotate Array
7. Merge Sorted Arrays
8. Majority Element
9. Intersection of Two Arrays
10. Maximum Product Subarray
BY: coding_error1
27. Add Two Numbers
28. Copy List with Random Pointer
29. Rotate List
30. Linked List Cycle II
BY: coding_error1
56. LCA in BST
57. Floor in BST
58. Ceil in BST
59. Serialize & Deserialize
60. Two Sum in BST
71. Subsets
72. Permutations
73. Combination Sum
74. N-Queens
75. Sudoku Solver
76. Word Search
77. Generate Parentheses
78. Rat in a Maze
79. Palindrome Partitioning
80. Phone Number Letter Combos
81. Fibonacci
82. Climbing Stairs
83. 🏚 House Robber
84. Longest Inc. Subsequence
BY: coding_error1
85. LCS – Longest Common Subseq.
86. 0/1 Knapsack
87. Coin Change
88. Edit Distance
89. Max Product Subarray
90. Palindromic Substrings
1. Two Sum
python
CopyEdit
def two_sum(nums, target):
hashmap = {}
for i, num in enumerate(nums):
complement = target - num
if complement in hashmap:
return [hashmap[complement], i]
hashmap[num] = i
BY: coding_error1
Problem: Maximize profit by choosing a day to buy and a future day to sell.
Approach: Track min price and max profit.
python
CopyEdit
def max_profit(prices):
min_price = float('inf')
profit = 0
for price in prices:
min_price = min(min_price, price)
profit = max(profit, price - min_price)
return profit
3. Contains Duplicate
python
CopyEdit
def contains_duplicate(nums):
return len(nums) != len(set(nums))
python
CopyEdit
def max_subarray(nums):
max_sum = curr = nums[0]
for num in nums[1:]:
curr = max(num, curr + num)
max_sum = max(max_sum, curr)
return max_sum
5. Move Zeroes
python
CopyEdit
def move_zeroes(nums):
pos = 0
for i in range(len(nums)):
if nums[i] != 0:
nums[pos], nums[i] = nums[i], nums[pos]
pos += 1
BY: coding_error1
6. Rotate Array
python
CopyEdit
def rotate(nums, k):
k %= len(nums)
nums[:] = nums[::-1]
nums[:k] = reversed(nums[:k])
nums[k:] = reversed(nums[k:])
python
CopyEdit
def merge(nums1, m, nums2, n):
i, j, k = m-1, n-1, m+n-1
while i >= 0 and j >= 0:
if nums1[i] > nums2[j]:
nums1[k] = nums1[i]
i -= 1
else:
nums1[k] = nums2[j]
j -= 1
k -= 1
nums1[:j+1] = nums2[:j+1]
8. Majority Element
python
CopyEdit
def majority_element(nums):
count = candidate = 0
for num in nums:
if count == 0:
candidate = num
count += (1 if num == candidate else -1)
return candidate
BY: coding_error1
Problem: Return the intersection of two arrays.
Approach: Use sets.
python
CopyEdit
def intersection(nums1, nums2):
return list(set(nums1) & set(nums2))
python
CopyEdit
def max_product(nums):
max_prod = min_prod = result = nums[0]
for num in nums[1:]:
temp = max(num, max_prod * num, min_prod * num)
min_prod = min(num, max_prod * num, min_prod * num)
max_prod = temp
result = max(result, max_prod)
return result
Problem: Check if two strings are anagrams (same letters, different order).
Approach: Compare character counts using collections.Counter.
python
CopyEdit
from collections import Counter
Problem: Return the length of the longest substring without repeating characters.
Approach: Use sliding window with a set.
python
BY: coding_error1
CopyEdit
def length_of_longest_substring(s):
seen = set()
left = max_len = 0
for right in range(len(s)):
while s[right] in seen:
seen.remove(s[left])
left += 1
seen.add(s[right])
max_len = max(max_len, right - left + 1)
return max_len
python
CopyEdit
def is_palindrome(s):
filtered = ''.join(c.lower() for c in s if c.isalnum())
return filtered == filtered[::-1]
python
CopyEdit
def longest_palindrome(s):
res = ""
for i in range(len(s)):
for a, b in [(i, i), (i, i+1)]: # odd and even length
while a >= 0 and b < len(s) and s[a] == s[b]:
a -= 1
b += 1
if b - a - 1 > len(res):
res = s[a+1:b]
return res
Problem: Compress the string using counts of repeated characters (e.g., aabcc →
a2b1c2).
Approach: Loop and count.
python
CopyEdit
def compress(chars):
i = 0
BY: coding_error1
res = []
while i < len(chars):
char = chars[i]
count = 0
while i < len(chars) and chars[i] == char:
count += 1
i += 1
res.append(char)
if count > 1:
res.extend(str(count))
chars[:] = res
return len(chars)
python
CopyEdit
def str_str(haystack, needle):
if not needle:
return 0
for i in range(len(haystack) - len(needle) + 1):
if haystack[i:i+len(needle)] == needle:
return i
return -1
python
CopyEdit
from collections import defaultdict
def group_anagrams(strs):
anagrams = defaultdict(list)
for s in strs:
key = ''.join(sorted(s))
anagrams[key].append(s)
return list(anagrams.values())
python
CopyEdit
BY: coding_error1
def multiply(num1, num2):
if num1 == "0" or num2 == "0": return "0"
res = [0] * (len(num1) + len(num2))
for i in reversed(range(len(num1))):
for j in reversed(range(len(num2))):
mul = int(num1[i]) * int(num2[j])
pos1, pos2 = i + j, i + j + 1
sum = mul + res[pos2]
res[pos2] = sum % 10
res[pos1] += sum // 10
result = ''.join(map(str, res)).lstrip('0')
return result
python
CopyEdit
def roman_to_int(s):
roman = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
total = prev = 0
for c in reversed(s):
val = roman[c]
if val < prev:
total -= val
else:
total += val
prev = val
return total
python
CopyEdit
def is_valid(s):
stack = []
mapping = {')': '(', ']': '[', '}': '{'}
for char in s:
if char in mapping.values():
stack.append(char)
elif char in mapping:
if not stack or stack.pop() != mapping[char]:
return False
else:
return False
return not stack
python
CopyEdit
def reverse_list(head):
prev = None
while head:
next_node = head.next
head.next = prev
prev = head
head = next_node
return prev
python
CopyEdit
def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
python
CopyEdit
def merge_two_lists(l1, l2):
if not l1 or not l2:
return l1 or l2
if l1.val < l2.val:
l1.next = merge_two_lists(l1.next, l2)
return l1
else:
l2.next = merge_two_lists(l1, l2.next)
return l2
BY: coding_error1
24. Palindrome Linked List
python
CopyEdit
def is_palindrome(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
prev = None
while slow:
tmp = slow.next
slow.next = prev
prev = slow
slow = tmp
while prev:
if head.val != prev.val:
return False
head = head.next
prev = prev.next
return True
Problem: Remove the n-th node from the end of the list.
Approach: Two pointer technique (fast and slow).
python
CopyEdit
def remove_nth_from_end(head, n):
dummy = ListNode(0, head)
fast = slow = dummy
for _ in range(n):
fast = fast.next
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return dummy.next
python
CopyEdit
def get_intersection_node(headA, headB):
BY: coding_error1
a, b = headA, headB
while a != b:
a = a.next if a else headB
b = b.next if b else headA
return a
python
CopyEdit
def add_two_numbers(l1, l2):
dummy = curr = ListNode(0)
carry = 0
while l1 or l2 or carry:
v1 = l1.val if l1 else 0
v2 = l2.val if l2 else 0
total = v1 + v2 + carry
carry = total // 10
curr.next = ListNode(total % 10)
curr = curr.next
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
return dummy.next
python
CopyEdit
def copy_random_list(head):
if not head: return None
curr = head
while curr:
copy = ListNode(curr.val)
copy.next = curr.next
curr.next = copy
curr = copy.next
curr = head
while curr:
if curr.random:
curr.next.random = curr.random.next
curr = curr.next.next
dummy = ListNode(0)
copy_curr = dummy
curr = head
while curr:
copy = curr.next
BY: coding_error1
curr.next = copy.next
copy_curr.next = copy
copy_curr = copy
curr = curr.next
return dummy.next
python
CopyEdit
def rotate_right(head, k):
if not head or not head.next or k == 0:
return head
length, tail = 1, head
while tail.next:
tail = tail.next
length += 1
k %= length
if k == 0:
return head
Problem: Find the node where the cycle begins (if any).
Approach: Use Floyd's algorithm, then find entry point.
python
CopyEdit
def detect_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
break
else:
return None
slow = head
while slow != fast:
slow = slow.next
BY: coding_error1
fast = fast.next
return slow
python
CopyEdit
def is_valid(s):
stack = []
mapping = {')':'(', '}':'{', ']':'['}
for char in s:
if char in mapping:
if not stack or stack.pop() != mapping[char]:
return False
else:
stack.append(char)
return not stack
Problem: Design a stack that supports push, pop, top, and retrieving the minimum
element in constant time.
Approach: Use two stacks – one for elements, one for current mins.
python
CopyEdit
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = []
def pop(self):
val = self.stack.pop()
if val == self.min_stack[-1]:
self.min_stack.pop()
def top(self):
return self.stack[-1]
def getMin(self):
return self.min_stack[-1]
BY: coding_error1
33. Queue via Stacks
python
CopyEdit
class MyQueue:
def __init__(self):
self.in_stack = []
self.out_stack = []
def pop(self):
self.peek()
return self.out_stack.pop()
def peek(self):
if not self.out_stack:
while self.in_stack:
self.out_stack.append(self.in_stack.pop())
return self.out_stack[-1]
def empty(self):
return not self.in_stack and not self.out_stack
Problem: For each day, find how many days to wait for a warmer temperature.
Approach: Use a monotonic decreasing stack.
python
CopyEdit
def daily_temperatures(temperatures):
res = [0] * len(temperatures)
stack = []
for i, t in enumerate(temperatures):
while stack and t > temperatures[stack[-1]]:
prev = stack.pop()
res[prev] = i - prev
stack.append(i)
return res
Problem: For each number in nums1, find the next greater in nums2.
Approach: Use a stack to map next greater for all nums2 elements.
BY: coding_error1
python
CopyEdit
def next_greater_element(nums1, nums2):
stack, greater = [], {}
for n in nums2:
while stack and n > stack[-1]:
greater[stack.pop()] = n
stack.append(n)
return [greater.get(n, -1) for n in nums1]
python
CopyEdit
def eval_rpn(tokens):
stack = []
for token in tokens:
if token in "+-*/":
b, a = stack.pop(), stack.pop()
if token == '+': stack.append(a + b)
elif token == '-': stack.append(a - b)
elif token == '*': stack.append(a * b)
else: stack.append(int(a / b))
else:
stack.append(int(token))
return stack[0]
python
CopyEdit
from collections import deque
BY: coding_error1
Problem: Simulate collisions between asteroids moving in opposite directions.
Approach: Use a stack to simulate and resolve collisions.
python
CopyEdit
def asteroid_collision(asteroids):
stack = []
for a in asteroids:
while stack and a < 0 < stack[-1]:
if stack[-1] < -a:
stack.pop()
continue
elif stack[-1] == -a:
stack.pop()
break
else:
stack.append(a)
return stack
python
CopyEdit
def simplify_path(path):
stack = []
for part in path.split("/"):
if part == "..":
if stack: stack.pop()
elif part and part != ".":
stack.append(part)
return "/" + "/".join(stack)
python
CopyEdit
def decode_string(s):
stack = []
curr_str = ''
num = 0
for c in s:
if c.isdigit():
num = num * 10 + int(c)
elif c == '[':
stack.append((curr_str, num))
curr_str, num = '', 0
elif c == ']':
BY: coding_error1
prev_str, repeat = stack.pop()
curr_str = prev_str + curr_str * repeat
else:
curr_str += c
return curr_str
python
CopyEdit
def inorder_traversal(root):
res, stack = [], []
while root or stack:
while root:
stack.append(root)
root = root.left
root = stack.pop()
res.append(root.val)
root = root.right
return res
python
CopyEdit
def preorder_traversal(root):
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
res.append(node.val)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
BY: coding_error1
Problem: Traverse left-right-root.
Approach: Use two stacks or modify preorder.
python
CopyEdit
def postorder_traversal(root):
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
res.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return res[::-1]
python
CopyEdit
from collections import deque
def level_order(root):
if not root:
return []
res, queue = [], deque([root])
while queue:
level = []
for _ in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level)
return res
python
CopyEdit
def max_depth(root):
if not root:
return 0
BY: coding_error1
return 1 + max(max_depth(root.left), max_depth(root.right))
python
CopyEdit
def diameter_of_binary_tree(root):
diameter = 0
def dfs(node):
nonlocal diameter
if not node:
return 0
left = dfs(node.left)
right = dfs(node.right)
diameter = max(diameter, left + right)
return 1 + max(left, right)
dfs(root)
return diameter
python
CopyEdit
def is_same_tree(p, q):
if not p and not q:
return True
if not p or not q:
return False
if p.val != q.val:
return False
return is_same_tree(p.left, q.left) and is_same_tree(p.right, q.right)
python
CopyEdit
def invert_tree(root):
if not root:
return None
root.left, root.right = invert_tree(root.right), invert_tree(root.left)
BY: coding_error1
return root
python
CopyEdit
def has_path_sum(root, target_sum):
if not root:
return False
if not root.left and not root.right:
return root.val == target_sum
return has_path_sum(root.left, target_sum - root.val) or
has_path_sum(root.right, target_sum - root.val)
python
CopyEdit
def lowest_common_ancestor(root, p, q):
if not root or root == p or root == q:
return root
left = lowest_common_ancestor(root.left, p, q)
right = lowest_common_ancestor(root.right, p, q)
if left and right:
return root
return left or right
python
CopyEdit
def search_bst(root, val):
if not root or root.val == val:
return root
if val < root.val:
return search_bst(root.left, val)
else:
return search_bst(root.right, val)
BY: coding_error1
52. Insert into BST
python
CopyEdit
def insert_into_bst(root, val):
if not root:
return TreeNode(val)
if val < root.val:
root.left = insert_into_bst(root.left, val)
else:
root.right = insert_into_bst(root.right, val)
return root
Problem: Delete node with given value in BST and maintain BST property.
Approach:
python
CopyEdit
def delete_node(root, key):
if not root:
return None
if key < root.val:
root.left = delete_node(root.left, key)
elif key > root.val:
root.right = delete_node(root.right, key)
else:
if not root.left:
return root.right
if not root.right:
return root.left
# Find inorder successor
succ = root.right
while succ.left:
succ = succ.left
root.val = succ.val
root.right = delete_node(root.right, succ.val)
return root
BY: coding_error1
Problem: Check if a binary tree is a valid BST.
Approach: Use bounds to validate each node’s value.
python
CopyEdit
def is_valid_bst(root, low=float('-inf'), high=float('inf')):
if not root:
return True
if not (low < root.val < high):
return False
return is_valid_bst(root.left, low, root.val) and
is_valid_bst(root.right, root.val, high)
python
CopyEdit
def kth_smallest(root, k):
stack = []
while True:
while root:
stack.append(root)
root = root.left
root = stack.pop()
k -= 1
if k == 0:
return root.val
root = root.right
python
CopyEdit
def lowest_common_ancestor_bst(root, p, q):
while root:
if p.val < root.val and q.val < root.val:
root = root.left
elif p.val > root.val and q.val > root.val:
root = root.right
else:
return root
BY: coding_error1
Problem: Find greatest value <= target in BST.
Approach: Traverse tree, update floor when node.val <= target.
python
CopyEdit
def floor_bst(root, target):
floor_val = None
while root:
if root.val == target:
return root.val
if root.val > target:
root = root.left
else:
floor_val = root.val
root = root.right
return floor_val
python
CopyEdit
def ceil_bst(root, target):
ceil_val = None
while root:
if root.val == target:
return root.val
if root.val < target:
root = root.right
else:
ceil_val = root.val
root = root.left
return ceil_val
python
CopyEdit
def serialize(root):
def preorder(node):
return [str(node.val)] + preorder(node.left) + preorder(node.right)
if node else []
return ','.join(preorder(root))
def deserialize(data):
def build(min_val, max_val):
if vals and min_val < vals[0] < max_val:
BY: coding_error1
val = vals.pop(0)
node = TreeNode(val)
node.left = build(min_val, val)
node.right = build(val, max_val)
return node
return None
vals = list(map(int, data.split(','))) if data else []
return build(float('-inf'), float('inf'))
python
CopyEdit
def find_target(root, k):
def inorder(node):
return inorder(node.left) + [node.val] + inorder(node.right) if
node else []
nums = inorder(root)
left, right = 0, len(nums) - 1
while left < right:
total = nums[left] + nums[right]
if total == k:
return True
elif total < k:
left += 1
else:
right -= 1
return False
python
CopyEdit
def binary_search(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
BY: coding_error1
62. Search in Rotated Sorted Array
python
CopyEdit
def search_rotated(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
if nums[left] <= nums[mid]:
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
python
CopyEdit
def find_median_sorted_arrays(nums1, nums2):
A, B = nums1, nums2
if len(A) > len(B):
A, B = B, A
m, n = len(A), len(B)
imin, imax, half_len = 0, m, (m + n + 1) // 2
while imin <= imax:
i = (imin + imax) // 2
j = half_len - i
if i < m and B[j-1] > A[i]:
imin = i + 1
elif i > 0 and A[i-1] > B[j]:
imax = i - 1
else:
if i == 0: max_of_left = B[j-1]
elif j == 0: max_of_left = A[i-1]
else: max_of_left = max(A[i-1], B[j-1])
if (m + n) % 2 == 1:
return max_of_left
if i == m: min_of_right = B[j]
elif j == n: min_of_right = A[i]
BY: coding_error1
else: min_of_right = min(A[i], B[j])
return (max_of_left + min_of_right) / 2.0
python
CopyEdit
def merge_sort(nums):
if len(nums) <= 1:
return nums
mid = len(nums) // 2
left = merge_sort(nums[:mid])
right = merge_sort(nums[mid:])
return merge(left, right)
python
CopyEdit
def quick_sort(nums):
def partition(low, high):
pivot = nums[high]
i = low
for j in range(low, high):
if nums[j] < pivot:
nums[i], nums[j] = nums[j], nums[i]
i += 1
nums[i], nums[high] = nums[high], nums[i]
return i
BY: coding_error1
quicksort_helper(p+1, high)
quicksort_helper(0, len(nums) - 1)
return nums
python
CopyEdit
def count_inversions(nums):
def merge_sort_count(arr):
if len(arr) <= 1:
return arr, 0
mid = len(arr) // 2
left, left_inv = merge_sort_count(arr[:mid])
right, right_inv = merge_sort_count(arr[mid:])
merged, split_inv = merge_count(left, right)
return merged, left_inv + right_inv + split_inv
_, total_inv = merge_sort_count(nums)
return total_inv
python
CopyEdit
import random
BY: coding_error1
for i in range(left, right):
if nums[i] > pivot:
nums[store_index], nums[i] = nums[i], nums[store_index]
store_index += 1
nums[right], nums[store_index] = nums[store_index], nums[right]
return store_index
python
CopyEdit
def find_peak_element(nums):
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[mid + 1]:
right = mid
else:
left = mid + 1
return left
python
CopyEdit
def search_insert(nums, target):
left, right = 0, len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid
return left
BY: coding_error1
70. Aggressive Cows
python
CopyEdit
def can_place_cows(stalls, cows, distance):
count = 1
last_position = stalls[0]
for i in range(1, len(stalls)):
if stalls[i] - last_position >= distance:
count += 1
last_position = stalls[i]
if count == cows:
return True
return False
71. Subsets
python
CopyEdit
def subsets(nums):
result = []
subset = []
def backtrack(index):
if index == len(nums):
result.append(subset[:])
return
# Include nums[index]
subset.append(nums[index])
backtrack(index + 1)
BY: coding_error1
# Exclude nums[index]
subset.pop()
backtrack(index + 1)
backtrack(0)
return result
72. Permutations
python
CopyEdit
def permute(nums):
result = []
def backtrack(start):
if start == len(nums):
result.append(nums[:])
return
for i in range(start, len(nums)):
nums[start], nums[i] = nums[i], nums[start]
backtrack(start + 1)
nums[start], nums[i] = nums[i], nums[start]
backtrack(0)
return result
python
CopyEdit
def combination_sum(candidates, target):
result = []
combination = []
backtrack(0, target)
return result
BY: coding_error1
74. N-Queens
python
CopyEdit
def solve_n_queens(n):
result = []
board = [["."] * n for _ in range(n)]
def backtrack(row):
if row == n:
result.append(["".join(r) for r in board])
return
for col in range(n):
if is_safe(row, col):
board[row][col] = "Q"
backtrack(row + 1)
board[row][col] = "."
backtrack(0)
return result
python
CopyEdit
def solve_sudoku(board):
def is_valid(r, c, val):
for i in range(9):
if board[r][i] == val or board[i][c] == val:
return False
box_row = (r // 3) * 3
box_col = (c // 3) * 3
BY: coding_error1
for i in range(box_row, box_row + 3):
for j in range(box_col, box_col + 3):
if board[i][j] == val:
return False
return True
def backtrack():
for i in range(9):
for j in range(9):
if board[i][j] == '.':
for val in map(str, range(1, 10)):
if is_valid(i, j, val):
board[i][j] = val
if backtrack():
return True
board[i][j] = '.'
return False
return True
backtrack()
python
CopyEdit
def exist(board, word):
rows, cols = len(board), len(board[0])
for i in range(rows):
for j in range(cols):
if dfs(i, j, 0):
return True
return False
BY: coding_error1
python
CopyEdit
def generate_parenthesis(n):
result = []
backtrack()
return result
Problem: Find path through maze from start to end moving only right/down.
Approach: Backtracking through valid paths.
python
CopyEdit
def rat_in_maze(maze):
n = len(maze)
path = []
res = []
path.append((0, 0))
maze[0][0] = -1
backtrack(0, 0)
return res
BY: coding_error1
python
CopyEdit
def palindrome_partition(s):
result = []
path = []
def is_palindrome(sub):
return sub == sub[::-1]
def backtrack(start):
if start == len(s):
result.append(path[:])
return
for end in range(start, len(s)):
if is_palindrome(s[start:end+1]):
path.append(s[start:end+1])
backtrack(end + 1)
path.pop()
backtrack(0)
return result
python
CopyEdit
def letter_combinations(digits):
if not digits:
return []
phone_map = {
"2": "abc", "3": "def", "4": "ghi", "5": "jkl",
"6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"
}
result = []
backtrack(0, "")
return result
81. Fibonacci
BY: coding_error1
Problem: Find nth Fibonacci number.
Approach: Use DP memoization or tabulation to avoid recomputation.
python
CopyEdit
def fibonacci(n):
if n <= 1:
return n
dp = [0] * (n+1)
dp[1] = 1
for i in range(2, n+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
python
CopyEdit
def climb_stairs(n):
if n <= 2:
return n
dp = [0]*(n+1)
dp[1], dp[2] = 1, 2
for i in range(3, n+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
python
CopyEdit
def house_robber(nums):
if not nums:
return 0
prev, curr = 0, 0
for num in nums:
prev, curr = curr, max(curr, prev + num)
return curr
BY: coding_error1
python
CopyEdit
def length_of_LIS(nums):
if not nums:
return 0
dp = [1]*len(nums)
for i in range(len(nums)):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j]+1)
return max(dp)
python
CopyEdit
def lcs(text1, text2):
m, n = len(text1), len(text2)
dp = [[0]*(n+1) for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if text1[i-1] == text2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
return dp[m][n]
python
CopyEdit
def knapsack(weights, values, W):
n = len(weights)
dp = [[0]*(W+1) for _ in range(n+1)]
for i in range(1, n+1):
for w in range(W+1):
if weights[i-1] <= w:
dp[i][w] = max(values[i-1] + dp[i-1][w - weights[i-1]],
dp[i-1][w])
else:
dp[i][w] = dp[i-1][w]
return dp[n][W]
BY: coding_error1
Problem: Minimum number of coins to make up an amount.
Approach: DP bottom-up approach.
python
CopyEdit
def coin_change(coins, amount):
dp = [float('inf')] * (amount + 1)
dp[0] = 0
for i in range(1, amount + 1):
for coin in coins:
if coin <= i:
dp[i] = min(dp[i], dp[i - coin] + 1)
return dp[amount] if dp[amount] != float('inf') else -1
python
CopyEdit
def min_distance(word1, word2):
m, n = len(word1), len(word2)
dp = [[0]*(n+1) for _ in range(m+1)]
for i in range(m+1):
dp[i][0] = i
for j in range(n+1):
dp[0][j] = j
for i in range(1, m+1):
for j in range(1, n+1):
if word1[i-1] == word2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
return dp[m][n]
python
CopyEdit
def max_product(nums):
if not nums:
return 0
max_prod = min_prod = result = nums[0]
for num in nums[1:]:
if num < 0:
max_prod, min_prod = min_prod, max_prod
max_prod = max(num, max_prod * num)
min_prod = min(num, min_prod * num)
result = max(result, max_prod)
BY: coding_error1
return result
python
CopyEdit
def count_palindromic_substrings(s):
count = 0
for i in range(len(s)):
expand_around_center(i, i) # odd length palindromes
expand_around_center(i, i+1) # even length palindromes
return count
python
CopyEdit
def num_islands(grid):
if not grid:
return 0
rows, cols = len(grid), len(grid[0])
count = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == '1':
dfs(r, c)
BY: coding_error1
count += 1
return count
python
CopyEdit
class Node:
def __init__(self, val = 0, neighbors = None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
def clone_graph(node):
if not node:
return None
visited = {}
def dfs(n):
if n in visited:
return visited[n]
copy = Node(n.val)
visited[n] = copy
for nei in n.neighbors:
copy.neighbors.append(dfs(nei))
return copy
return dfs(node)
python
CopyEdit
def has_cycle_undirected(graph):
visited = set()
BY: coding_error1
return True
return False
python
CopyEdit
def has_cycle_directed(graph):
visited = set()
rec_stack = set()
def dfs(node):
visited.add(node)
rec_stack.add(node)
for nei in graph[node]:
if nei not in visited:
if dfs(nei):
return True
elif nei in rec_stack:
return True
rec_stack.remove(node)
return False
python
CopyEdit
def topological_sort(graph):
visited = set()
stack = []
def dfs(node):
visited.add(node)
for nei in graph[node]:
if nei not in visited:
dfs(nei)
stack.append(node)
BY: coding_error1
96. Shortest Path (Unweighted Graph)
Problem: Find shortest path length from start node to all others in unweighted graph.
Approach: BFS.
python
CopyEdit
from collections import deque
while queue:
node = queue.popleft()
for nei in graph[node]:
if dist[nei] == float('inf'):
dist[nei] = dist[node] + 1
queue.append(nei)
return dist
python
CopyEdit
import heapq
while heap:
current_dist, node = heapq.heappop(heap)
if current_dist > dist[node]:
continue
for nei, weight in graph[node]:
distance = current_dist + weight
if distance < dist[nei]:
dist[nei] = distance
heapq.heappush(heap, (distance, nei))
return dist
BY: coding_error1
Problem: Change color of connected region in 2D grid.
Approach: DFS or BFS to fill adjacent cells.
python
CopyEdit
def flood_fill(image, sr, sc, new_color):
old_color = image[sr][sc]
if old_color == new_color:
return image
rows, cols = len(image), len(image[0])
dfs(sr, sc)
return image
Problem: Check if graph nodes can be colored with two colors without adjacent nodes
having same color.
Approach: BFS or DFS coloring.
python
CopyEdit
def is_bipartite(graph):
color = {}
for node in graph:
if node not in color:
stack = [node]
color[node] = 0
while stack:
u = stack.pop()
for v in graph[u]:
if v not in color:
color[v] = 1 - color[u]
stack.append(v)
elif color[v] == color[u]:
return False
return True
BY: coding_error1
python
CopyEdit
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0]*n
BY: coding_error1