I decided to redo this problem, from the archives in Python. Previously I had it in C++. You’d think this post, then, of resizing a 2D array, would have been straightforward. Here are some notes:
- The key insight (in my approach, at least) is that assuming the resize is valid, there are r*c elements, and we can define helper functions like getRow and getColumn that take an i, and an r, c dimensions, and return the row and column of the ith element. In this way we can walk through the arrays “in parallel”
- I hit an issue with some terse way of allocating an array in python. It seems something like [[0]*c]*r leads to shallow copies in some cases, and that tripped me up.
- Then, of course, I managed to get R and C mixed up.
I think this is a good exercise for junior people who say they feel comfortable with 2D arrays.
Complete with debugging statements, here is my approach:
def getRow(i, r, c):
#print('row of', i, '-th element in matrix ', r, '*', c, 'is', i // c)
return i // c
def getCol(i, r, c):
return i % c
class Solution:
def matrixReshape(self, mat: List[List[int]], r: int, c: int) -> List[List[int]]:
R = len(mat)
if R is 0: return mat
C = len(mat[0])
if R * C != r * c:
return mat
res = []
for i in range(r):
res.append([])
for j in range(c):
res[i].append(0)
for i in range(r*c):
#print(getRow(i, r, c), getCol(i, r, c), getRow(i, R, C), getCol(i, R, C))
old = mat[getRow(i, R, C)][getCol(i, R, C)]
res[getRow(i, r, c)][getCol(i, r, c)] = old
return res
Take-Aways
This covers interesting questions like allocation (pre-allocating the results array), bounds-checking in a nontrivial setting (numrows, numcols), and then an interesting question of mapping. That mapping also really requires a comfort with indices versus the values of an array, plus array-of-arrays instead of just arrays. I think this is a good “hard” phone-screen question.
For real-world applicability, I’ve never worked too much with 2D arrays, certainly not this explicitly. However, the challenge of iterating over 2 different objects/data-structures that don’t naively both map to the same for loop (so to speak), that’s something that comes up a lot, albeit not so directly as in this code. Just recently I was iterating over 2 similar (but not the same!) trees at work, and had to make sure the iteration remains in lockstep. Of course, this complex-iteration also comes up in my favorite merge-linked-list sort of questions. Again, not literally identical, but the same “genus”.