DSA Patterns Flashcards

1
Q

Pattern used to search or operate on a pair of elements in an array

A

Two pointers. Ex Two Sum II, 3 Sum, Container with most water.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Pattern to more optimally calculate the sum of a subset of elements in an array

A

Prefix Sum. Ex Range Sum Query, Contiguous Array, Subarray Sum

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Prefix Sum initialization and formula to find sum of subset

A

Initialization:
new Array(nums.length + 1).fill(0)

This sets up an array with an extra space for the initial sum of 0, and sets all other values to zero until they are summed.

Formula:
Sum(l, r) = prefixSum[r + 1] - prefixSum[l]

Subtracts the total sum just before the left pointer from the sum at the right pointer

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Pattern to find or operate on a subset of an array

A

Sliding Window. Move two pointers to define the subset. Ex Max Avg Subarray, Longest Substring without Repeating Chars, Min Window Substring.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Pattern to find cycles and dupes

A

Fast and Slow Pointers. Ex Linked List Cycle, Happy Number, Find duplicate number

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Properties of a Linked List and Node

A

LinkedList: head, size
Node: data, next

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Linked List Insert First

A

Create a new node with the data and the current head as it’s next, then set the new node as the head.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Linked List Insert Last

A

Set a current variable to the head. Then loop through while the current node has a next value and if it does setting next as the new current. When the current.next is null you are at the end of the list and can set current.next to a new node

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Linked List Insert at Index

A

If the index is greater than size exit function. If index is 0 then just invoke insert first method. Initialize variables for the current node, the previous node, and a count. While looping, set previous to current, increment count, and set current to next. Once count == index exit loop. Set new node next to current, set previous.next to new node.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Linked List GetAt

A

Initialize count variable and loop while count < index then return current

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Linked List Remove At

A

Use current, previous, count and while loop to find node at index and identify its previous and next nodes. Then set previous.next to current.next, effectively removing current from the list

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Linked List Reversal

A

Cur, prev, next variables. While there is a cur:
next = cur.next
cur.next = prev
prev = cur
cur = next

After loop, prev will be the new head so set this.head to prev

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Linked List Reverse with Stack

A

Push all nodes into stack, then while the stack has elements, pop them off and set to the current.next then set current to current.next (the popped off element). Set last next pointer to null

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Linked List Clear

A

this.head = null

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Reverse Doubly Linked List

A

While (current)
temp = current.prev
current.prev = current.next
current.next = temp

current = current.prev

at the end temp will be pointing to new head
this.head = temp.prev

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Pattern to find the k smallest or k largest

A

Heaps. Min heap for k largest, max heap for k smallest.

17
Q

Formula to calculate the distance between two points on a plot

A

Math.sqrt((x1 - x2)^2 + (y1 - y2)^2) = distance

18
Q

Get parent, right child, left child in a heap or binary tree

A

Parent idx = Math.floor((i- 1) / 2)

Left child idx = 2 * i + 1

Right child idx = 2 * i + 2

19
Q

Adding to a heap

A

Push to heap (add lead) and heapify up

Set idx to last idx. While idx > 0

Get parent idx. Compare heap[idx] to heap[parentIdx] and switch them if needed. If not needed, break the loop

20
Q

Replacing an element in a heap (heap already has k elements and new element is larger/smaller than max/min)

A

Set root (heap[0]) to new element then heapify down

Set idx to 0. While true
Set largest/smallest idx for min/max heap respectively to idx. Get idx for left and right children. Compare left child the right child to largest/smallest and reassign largest/smallest as necessary. If largest/smallest still equals idx then break. If not switch element at idx with element at largest/smallest and set idx to largest/smallest idx

21
Q

Binary tree pre order

A

DFS - root, left, right

22
Q

Binary tree in order

A

DFS - left, root, right

23
Q

Binary tree post order

A

DFS - left, right, root

24
Q

Binary tree level order

A

BFS

25
Q

How to determine binary tree DFS order

A

“When processing a node, do I need information from the children first?”

If yes - post order
If no and tree is BST - in order
If no and need to decide process at parent - pre order

26
Q

Binary tree DFS process

A

Recursively call method with each child as the new root

27
Q

Binary tree BFS

A

Set a queue and add root. While queue has elements
Initialize current level array
Set levelsize to queue length
Loop levelsize amount of times, dequeue (shift) node and if not null push val to current level and push left and right children to queue. Exit inner loop and restart outer loop

28
Q

DFS

A

Depth first search. Recursively call on child or top/bottom/left/right element in a matrix

29
Q

BFS

A

Use queue to add children or top/bottom/left/right elements of matrix. Use whole loop, then set queue size to a variable (because size will change) and do a for loop where you pop off the next in line, process it, and potentially add more to the queue. Then the while loop starts again with new queue size

30
Q

Matrix directions

A

let directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]

for (let [dr, dc] of directions

31
Q

How do you implement a Queue with O(1) retrieval?

A

Set the data property to a hash map. Add a front idx and back idx property and initialize at 0 for both. When adding an element, add the current back idx as the key and the element as the value, then increment back idx. When retrieving an element, retrieve the front idx key, save the value to a variable. Delete the element (delete this.data[this.front]) then increment front idx. Can also add size property. Check if it’s clear when front idx == back idx

32
Q

What is an adjacency list?

A

It’s a list representation of a graph, usually a hash map or array. For hash map the key is the vertex and the value is a list of vertices connected to that vertex by an edge. For array the index is the vertex and subarray is list of vertices

33
Q

Graph vertices and edges

A

A vertex or vertices are nodes or points on the graph. Edges are the connection between two vertices and they can be directed (one way) or undirected

34
Q

LRU Cache

A

Initialize with capacity property and cache property (Map).

Get method checks if cache has key. If so it sets value to a variable, deletes the key, sets the key again with the value from the v variable then return the value.

Put method checks for key and deletes if it exists. If it doesn’t exist but cache is at capacity then use Map iterator (this.cache.keys()) to get least recent (iterator.next().value) and delete it. Then add the new key and value.

This can also be implemented with a doubly linked list.

35
Q

What makes a graph tree valid?

A

All nodes connected, no cycles

36
Q

What makes a graph tree valid?

A

All nodes connected, no cycles

37
Q

Backtracking

A

Build a solution incrementally and backtrack when the current path of choices won’t lead to a valid solution. Used for search, permutation, combination

38
Q

SOLID

A

Single responsibility principle - every class has one responsibility

Open-closed principle - classes should be open for extension but closed for modification

Liskov substitution principle - functions with references to base classes must be able to use objects of derived classes without knowing it

Interface segregation principle - clients should not be forced to depend on interfaces they don’t use

Dependency inversion principle - depend upon abstractions not concretes