Strategies for matrix
Write an efficient algorithm that searches for a target value in an m x n integer matrix. The matrix has the following properties:
Integers in each row are sorted in ascending from left to right.
Integers in each column are sorted in ascending from top to bottom.
brute is getting the smallest row/col, then do linear loop through smallest one and binary search through the larger one. O(n log m) time and constant space. You can optimize it with a diagonal binary search too.
time: O(n + m), worst case it is in the top right
space: O(1), no space
class Solution:
divide and conquer
time: O(n logN)
space: O(log(n)) bc each divide can require logN space
class Solution3:
——–return self.helper(i, left, bottom, mid-1, matrix, target) or self.helper(top, mid+1, i-1, right, matrix, target)
n-qeeuns 2
The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other.
Given an integer n, return the number of distinct solutions to the n-queens puzzle.
brute force would be to generate all combinations of squares with N queens, see if they are attacking, return each time they are not, n^n time
Custom solution, not optimal but better than brute force. N!*N^2 time (initial backtracking loop + placing a queen and incrementing numbers on matrix), N^2 space for matrix
time: O(N!), bc of backtracking this makes sense bc each row has N…N-1…1 options to go through
space: N, the 3 sets each take of N space, the recursion on backtracking will only go N deep as well
class Solution:
pacific atlantic water flow
There is an m x n rectangular island that borders both the Pacific Ocean and Atlantic Ocean. The Pacific Ocean touches the island’s left and top edges, and the Atlantic Ocean touches the island’s right and bottom edges.
The island is partitioned into a grid of square cells. You are given an m x n integer matrix heights where heights[r][c] represents the height above sea level of the cell at coordinate (r, c).
The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell’s height is less than or equal to the current cell’s height. Water can flow from any cell adjacent to an ocean into the ocean.
Return a 2D list of grid coordinates result where result[i] = [ri, ci] denotes that rain water can flow from cell (ri, ci) to both the Pacific and Atlantic oceans.
brute force is a double for loop, with a DFS on each item to search if it touches both atlantic and pacific by setting the “goal” values. this is (m*n)^2 bc each iteration can go through all the other points. We also need to make sure we don’t get an infinite loop by tracking which points we have been to on each iteration
DFS/BFS have same time/space
time: O(n * m), we have to check each point, if each point has the same height, we check them both for each ocean
space: O(n * m), the sets can, in the worst case, hold all points in the matrix. The queue/recurion stack for DFS could also hold all the points at once
class BFS:
class DFS:
search 2d matrix 1
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.
brute force is linear search, or linear/binary search at NlogN time
time: O(log(n * m) where n*m is the total size of the matrix
space: constant
class Solution:
diagonal traversal
Given an m x n matrix mat, return an array of all the elements of the array in a diagonal order.
time: O(N * M), or linear in terms of elements in the matrix
space: constant, other than the output array.
class Solution:
n queens
The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle. You may return the answer in any order.
Each solution contains a distinct board configuration of the n-queens’ placement, where ‘Q’ and ‘.’ both indicate a queen and an empty space, respectively.
time: O(N!), you may think we add N^2 to it bc we have to append the board state to the response, but that can only happen N times because it only happens at the end of the solution. meaning it is N! + n*N^2, so N! is larger.
space: O(N^2), space for the empty board
class Solution:
spiral matrix
Given an m x n matrix, return all elements of the matrix in spiral order.
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]
time: O(n*m) which is the total size of the matrix
space: constant
class Solution:
—-def spiralOrder(self, matrix):
——–response = []
——–right, left, up, down = Direction(“right”), Direction(“left”), Direction(“up”), Direction(“down”)
——–right.next, left.next, up.next, down.next = down, up, right, left
——–state = StateMachine(right)
——–left, up = 0, 0
——–rows, cols = len(matrix), len(matrix[0])
——–down = rows - 1
——–right = cols - 1
——–
——–while len(response) < rows * cols:
————if state.state.direction == “right”:
—————-for i in range(left, right + 1):
——————–response.append(matrix[up][i])
—————-up += 1
—————-state.transition()
————elif state.state.direction == “down”:
—————-for i in range(up, down + 1):
——————–response.append(matrix[i][right])
—————-right -= 1
—————-state.transition()
————
————elif state.state.direction == “left”:
—————-for i in range(right, left - 1, -1):
——————–response.append(matrix[down][i])
—————-down -= 1
—————-state.transition()
————
————elif state.state.direction == “up”:
—————-for i in range(down, up - 1, -1):
——————–response.append(matrix[i][left])
—————-left += 1
—————-state.transition()
——–return response
————————
class StateMachine:
—-def __init__(self, state):
——–self.state = state
—-
—-def get_direction(self):
——–return self.state.direction
—-
—-def transition(self):
——–self.state = self.state.next
————
class Direction:
—-def __init__(self, direction):
——–self.direction = direction
——–self.next = None
class Solution:
—-def spiralOrder(self, matrix):
——–response = []
——–state = Direction()
——–left, up = 0, 0
——–rows, cols = len(matrix), len(matrix[0])
——–down = rows - 1
——–right = cols - 1
——–
——–while len(response) < rows * cols:
————if state.direction == “right”:
—————-for i in range(left, right + 1):
——————–response.append(matrix[up][i])
—————-up += 1
—————-state.transition()
————elif state.direction == “down”:
—————-for i in range(up, down + 1):
——————–response.append(matrix[i][right])
—————-right -= 1
—————-state.transition()
————
————elif state.direction == “left”:
—————-for i in range(right, left - 1, -1):
——————–response.append(matrix[down][i])
—————-down -= 1
—————-state.transition()
————
————elif state.direction == “up”:
—————-for i in range(down, up - 1, -1):
——————–response.append(matrix[i][left])
—————-left += 1
—————-state.transition()
——–return response
————————
——–
class Direction:
—-def __init__(self):
——–self.direction = “right”
—-
—-def get_direction(self):
——–return self.direction
—-
—-def transition(self):
————self.direction = “down”
——–elif self.direction == “down”:
————self.direction = “left”
——–elif self.direction ==”left”:
————self.direction = “up”
——–elif self.direction == “up”:
————self.direction = “right”
minimum sub array
Given an array of positive integers nums and a positive integer target, return the minimal length of a contiguous subarray [numsl, numsl+1, …, numsr-1, numsr] of which the sum is greater than or equal to target. If there is no such subarray, return 0 instead.
Example 1:
Input: target = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: The subarray [4,3] has the minimal length under the problem constraint.
Example 2:
Input: target = 4, nums = [1,4,4]
Output: 1
brute force is n^2, do a double for loop
time: O(N), worse case we could see each element twice, so maybe 2N
space: constant, we do not create new ds’s
class Solution: