Below is a structured, visual, and templated explanation for core algorithmic patterns. Each includes:
- โ Problem Statement
- ๐ง Pattern / Strategy Used
- ๐ Why that pattern works here
- โ๏ธ Pseudocode (before coding)
- ๐งญ Flow (decision-making or diagram)
- ๐ง Code using
Input โ Logic โ Output
template
๐ช 1. Sliding Window โ Max Sum of Subarray of Size K
โ Problem:
Find the maximum sum of any subarray of size
k
from a list of positive integers.
๐ง Pattern: Sliding Window
๐ Why Sliding Window?
We can reuse previous calculations to avoid recalculating the sum for overlapping subarrays.
โ๏ธ Pseudocode:
1. Initialize window_sum with sum of first k elements
2. max_sum = window_sum
3. Slide window from left to right:
- Subtract leftmost element
- Add new rightmost element
- Update max_sum
๐งญ Flow:
[1, 2, 3, 4, 5], k = 3
Window 1: sum(1,2,3) = 6
Window 2: Remove 1, add 4 => sum = 9
Window 3: Remove 2, add 5 => sum = 12 (max)
๐ง Code:
def get_input():
return [1, 2, 3, 4, 5], 3
def process(arr_k):
arr, k = arr_k
window_sum = sum(arr[:k])
max_sum = window_sum
for i in range(k, len(arr)):
window_sum = window_sum - arr[i-k] + arr[i]
max_sum = max(max_sum, window_sum)
return max_sum
def show_result(output):
print("Max sum of subarray:", output)
def main():
data = get_input()
result = process(data)
show_result(result)
main()
๐ 2. Two Pointers โ Remove Duplicates in Sorted Array
โ Problem:
Remove duplicates in-place from a sorted array. Return the new length.
๐ง Pattern: Two Pointers
๐ Why Two Pointers?
Track one slow pointer for the unique part, and one fast pointer for scanning.
โ๏ธ Pseudocode:
1. If empty, return 0
2. Set slow = 0
3. Loop fast from 1 to end:
- if arr[fast] != arr[slow]:
slow += 1
arr[slow] = arr[fast]
4. Return slow + 1 (length of unique array)
๐งญ Flow:
Input: [1,1,2,2,3]
S F
[1,2,2,2,3] โ [1,2,3,...]
๐ง Code:
def get_input():
return [1, 1, 2, 2, 3]
def process(arr):
if not arr:
return 0
slow = 0
for fast in range(1, len(arr)):
if arr[fast] != arr[slow]:
slow += 1
arr[slow] = arr[fast]
return slow + 1
def show_result(output):
print("Length of unique array:", output)
def main():
data = get_input()
result = process(data)
show_result(result)
main()
๐ 3. Backtracking โ Subsets of a List
โ Problem:
Given a list of distinct integers, return all possible subsets (power set).
๐ง Pattern: Backtracking
๐ Why Backtracking?
We build the decision tree of including or excluding each number.
โ๏ธ Pseudocode:
1. Start with empty path []
2. At each step:
- Add current path to result
- Recurse for each remaining element:
โ Include element
โ Backtrack
๐งญ Flow (for [1,2]):
[]
/ \
[1] []
/ \ \
[1,2] [1] [2]
๐ง Code:
def get_input():
return [1, 2]
def process(nums):
result = []
def backtrack(start, path):
result.append(path[:])
for i in range(start, len(nums)):
path.append(nums[i])
backtrack(i+1, path)
path.pop()
backtrack(0, [])
return result
def show_result(output):
print("All subsets:", output)
def main():
data = get_input()
result = process(data)
show_result(result)
main()
๐งฎ 4. Dynamic Programming โ Fibonacci with Memoization
โ Problem:
Return the nth Fibonacci number.
๐ง Pattern: Dynamic Programming (Top-Down)
๐ Why DP?
Repetitive subproblems โ solve once, store result.
โ๏ธ Pseudocode:
fib(n):
if n in memo:
return memo[n]
if n <= 1:
return n
memo[n] = fib(n-1) + fib(n-2)
return memo[n]
๐งญ Flow:
fib(5) โ fib(4) + fib(3)
โ fib(3) + fib(2) + fib(2) + fib(1)
โ reuse fib(2), fib(3) from memo
๐ง Code:
def get_input():
return 6
def process(n):
memo = {}
def fib(x):
if x in memo:
return memo[x]
if x <= 1:
return x
memo[x] = fib(x - 1) + fib(x - 2)
return memo[x]
return fib(n)
def show_result(output):
print("Fibonacci number is:", output)
def main():
data = get_input()
result = process(data)
show_result(result)
main()
โฌ 5. Matrix Traversal โ Spiral Order
โ Problem:
Return all elements of a matrix in spiral order.
๐ง Pattern: Matrix Traversal (Boundary shrink)
๐ Why Matrix Traversal?
Use 4 boundaries: top, bottom, left, right.
โ๏ธ Pseudocode:
while top <= bottom and left <= right:
โ Traverse top row
โ Traverse right col
โ Traverse bottom row
โ Traverse left col
โ Shrink boundaries
๐งญ Flow:
1 2 3
4 5 6
7 8 9
โ โ โ
โ โ
โ โ โ
โ
๐ง Code:
def get_input():
return [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
def process(matrix):
res = []
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while top <= bottom and left <= right:
for i in range(left, right + 1): # Top row
res.append(matrix[top][i])
top += 1
for i in range(top, bottom + 1): # Right column
res.append(matrix[i][right])
right -= 1
if top <= bottom:
for i in range(right, left - 1, -1): # Bottom row
res.append(matrix[bottom][i])
bottom -= 1
if left <= right:
for i in range(bottom, top - 1, -1): # Left column
res.append(matrix[i][left])
left += 1
return res
def show_result(output):
print("Spiral order:", output)
def main():
data = get_input()
result = process(data)
show_result(result)
main()
Leave a Reply