Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.

Example:


Input: 3
Output:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]

Difficulty: MEDIUM_HARD
Starter code: class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        

Solutions:
class Solution:

	def generateMatrix(self, n):
		if n < 1:
			return []
		left = 0
		right = n - 1
		up = 0
		bottom = n - 1
		self.matrix = [[0 for i in range(n)] for j in range(n)]
		count = 1
		while left <= right:
			if left < right:
				count = self.DrawRow(up, left, right, count)
				count = self.DrawCol(right, up, bottom, count)
				count = self.DrawRow(bottom, right, left, count)
				count = self.DrawCol(left, bottom, up, count)
			else:
				count = self.DrawCol(left, up, bottom + 1, count)
				break
			up += 1
			bottom += -1
			left += 1
			right += -1
		return self.matrix

	def DrawRow(self, row, start, end, value):
		add = 1
		if start > end:
			add = -1
		for i in range(start, end, add):
			self.matrix[row][i] = value
			value += 1
		return value

	def DrawCol(self, col, start, end, value):
		add = 1
		if start > end:
			add = -1
		for i in range(start, end, add):
			self.matrix[i][col] = value
			value += 1
		return value


class Solution:

	def generateMatrix(self, n):
		matrix = [[0 for i in range(n)] for i in range(n)]
		(start, end) = (0, n - 1)
		count = 1
		for j in range(int(n / 2)):
			for i in range(start, end + 1):
				matrix[start][i] = count
				count += 1
			for i in range(start + 1, end + 1):
				matrix[i][end] = count
				count += 1
			for i in range(end - 1, start - 1, -1):
				matrix[end][i] = count
				count += 1
			for i in range(end - 1, start, -1):
				matrix[i][start] = count
				count += 1
			start += 1
			end -= 1
		if n % 2 != 0:
			matrix[start][end] = count
		return matrix


class Solution:

	def generateMatrix(self, n):
		res = [[0 for i in range(n)] for j in range(n)]
		(count, rowNum) = (1, n)
		(rowIndex1, rowIndex2, colIndex1, colIndex2) = (0, n - 1, n - 1, 0)
		while rowNum >= 1:
			for i in range(colIndex2, colIndex1 + 1):
				res[rowIndex1][i] = count
				count += 1
			rowIndex1 += 1
			for i in range(rowIndex1, rowIndex2 + 1):
				res[i][colIndex1] = count
				count += 1
			colIndex1 -= 1
			for i in range(colIndex1, colIndex2 - 1, -1):
				res[rowIndex2][i] = count
				count += 1
			rowIndex2 -= 1
			for i in range(rowIndex2, rowIndex1 - 1, -1):
				res[i][colIndex2] = count
				count += 1
			colIndex2 += 1
			rowNum -= 2
		return res


class Solution:

	def generateMatrix(self, n):
		if n == 0:
			return []
		elif n == 1:
			return [[1]]
		cnt = 1
		ret = [[None] * n for _ in range(n)]

		def layer(width, margin):
			if not width > 0:
				return
			nonlocal cnt
			for i in range(margin, margin + width):
				ret[margin][i] = cnt
				cnt += 1
			for i in range(margin + 1, margin + width):
				ret[i][margin + width - 1] = cnt
				cnt += 1
			for i in range(margin + width - 2, margin - 1, -1):
				ret[margin + width - 1][i] = cnt
				cnt += 1
			for i in range(margin + width - 2, margin, -1):
				ret[i][margin] = cnt
				cnt += 1
			layer(width - 2, margin + 1)
		layer(n, 0)
		return ret


class Solution:

	def generateMatrix(self, n):
		matrix = []
		if n == 0:
			return matrix
		matrix = [[0] * n for i in range(n)]
		rowBegin = 0
		rowEnd = n - 1
		colBegin = 0
		colEnd = n - 1
		num = 0
		while True:
			for j in range(colBegin, colEnd + 1):
				num += 1
				matrix[rowBegin][j] = num
			rowBegin += 1
			if rowBegin > rowEnd:
				break
			for j in range(rowBegin, rowEnd + 1):
				num += 1
				matrix[j][colEnd] = num
			colEnd -= 1
			if colBegin > colEnd:
				break
			for j in range(colEnd, colBegin - 1, -1):
				num += 1
				matrix[rowEnd][j] = num
			rowEnd -= 1
			if rowBegin > rowEnd:
				break
			for j in range(rowEnd, rowBegin - 1, -1):
				num += 1
				matrix[j][colBegin] = num
			colBegin += 1
			if colBegin > colEnd:
				break
		return matrix


class Solution:

	def generateMatrix(self, n):
		t = 1
		temp = []
		for i in range(n):
			temp.append([None] * n)
		rep = int(n / 2) if n % 2 == 0 else int(n / 2) + 1
		k = 1
		for i in range(rep):
			for j in range(i, n - i - 1):
				temp[i][j] = k
				k += 1
			for j in range(i, n - i - 1):
				temp[j][n - i - 1] = k
				k += 1
			for j in range(n - i - 1, i, -1):
				temp[n - i - 1][j] = k
				k += 1
			for j in range(n - i - 1, i, -1):
				temp[j][i] = k
				k += 1
		if n % 2 == 1:
			temp[int(n / 2)][int(n / 2)] = n * n
		return temp


class Solution:

	def generateMatrix(self, n):
		left = 0
		top = 0
		right = n - 1
		bottom = n - 1
		res = [[0 for _ in range(n)] for _ in range(n)]
		num = 1
		while left < right and top < bottom:
			for i in range(left, right):
				res[top][i] = num
				num += 1
			for i in range(top, bottom):
				res[i][right] = num
				num += 1
			for i in range(right, left, -1):
				res[bottom][i] = num
				num += 1
			for i in range(bottom, top, -1):
				res[i][left] = num
				num += 1
			left += 1
			right -= 1
			top += 1
			bottom -= 1
		if left == right and top == bottom:
			res[left][top] = num
		return res


class Solution:

	def generateMatrix(self, n):
		retv = [[0 for i in range(n)] for j in range(n)]
		num = n * n
		(i, j, di, dj) = (0, 0, 0, 1)
		for k in range(1, num + 1):
			retv[i][j] = k
			if retv[(i + di) % n][(j + dj) % n]:
				(di, dj) = (dj, -di)
			i += di
			j += dj
		return retv


class Solution:

	def generateMatrix(self, n):
		arr = [a for a in range(1, n * n + 1)]
		matrix = [[a for a in range(1, n + 1)] for b in range(1, n + 1)]
		num = 0
		row_s = 0
		row_e = n - 1
		col_s = 0
		col_e = n - 1
		while col_e > col_s and row_e > row_s:
			for i in range(col_s, col_e):
				matrix[row_s][i] = arr[num]
				num += 1
			for i in range(row_s, row_e):
				matrix[i][col_e] = arr[num]
				num += 1
			for i in range(col_e, col_s, -1):
				matrix[row_e][i] = arr[num]
				num += 1
			for i in range(row_e, row_s, -1):
				matrix[i][col_s] = arr[num]
				num += 1
			row_s += 1
			col_s += 1
			row_e -= 1
			col_e -= 1
		if col_s == col_e:
			for i in range(row_s, row_e + 1):
				matrix[i][col_e] = arr[num]
				num += 1
		else:
			for i in range(col_s, col_e + 1):
				matrix[row_s][i] = arr[num]
				num += 1
		return matrix


class Solution:

	def generateMatrix(self, n):
		if n == 0:
			return []
		res = [[0] * n for _ in range(n)]
		record = set()
		(rupper, rdown, cleft, cright, val) = (0, n - 1, 0, n - 1, 1)
		while rupper < rdown and cleft < cright:
			for col in range(cleft, cright):
				res[rupper][col] = val
				val += 1
			for row in range(rupper, rdown):
				res[row][cright] = val
				val += 1
			for col in range(cright, cleft, -1):
				res[rdown][col] = val
				val += 1
			for row in range(rdown, rupper, -1):
				res[row][cleft] = val
				val += 1
			rupper += 1
			rdown -= 1
			cleft += 1
			cright -= 1
		if n % 2 != 0:
			res[n // 2][n // 2] = val
		return res


class Solution:

	def generateMatrix(self, n):
		if n == 0:
			return []
		nums = list(range(1, n * n + 1))
		matrix = [[nums[-1]]]
		start = n * n - 1
		while start > 0:
			matrix = matrix[::-1]
			matrix = [*zip(*matrix)]
			matrix = [nums[start - len(matrix[0]):start]] + matrix
			start = start - len(matrix[0])
		return [*map(list, matrix)]