Intuition
- This problem is similar to Spiral Matrix II, it is recommended to do that before doing this.
Approach
- Changing directions:
- In a normal graph/matrix DFS traversal, you normally always prioritizing 1 direction, for example always going up if possible. This time, it is required for you to only going in 1 direction, and change it according to a pattern: right -> down -> left -> up.
- You can do exactly that, keep going in 1 direction and only change direction when encounter boundary.
- Create a result 2d array and fill it with -1 then travese it in spiral direction, at every index fill the value of current node from input linked-list in it. You stop when you reach the end of the linked-list.
Complexity
- Time complexity: O(N) Every node of the linked-list is visited only once
- Space complexity: O(1) It actually O(N) if you count the call stack
Code
C++
class Solution {
public:
vector<vector<int>> spiralMatrix(int m, int n, ListNode* head) {
vector<vector<int>> res(m, vector<int>(n, -1));
vector<pair<int, int>> directions = {
{0, 1}, {1, 0}, {0, -1}, {-1, 0}
};
move(res, m, n, 0, 0, head, 0, directions);
return res;
}
void move(vector<vector<int>> &res, int m, int n, int row, int col, ListNode* head, int dir, vector<pair<int, int>> &directions) {
if(min(row, col) < 0 || row > m-1 || col > n-1) return;
if(!head) return;
res[row][col] = head->val;
head = head->next;
int nextRow = row + directions[dir].first;
int nextCol = col + directions[dir].second;
bool out_bound_h = (nextRow < 0 || nextRow > m-1);
bool out_bound_w = nextCol < 0 || nextCol > n-1;
if (out_bound_h || out_bound_w || res[nextRow][nextCol] != -1) {
dir = (dir + 1) % 4;
nextRow = row + directions[dir].first;
nextCol = col + directions[dir].second;
}
move(res, m, n, nextRow, nextCol, head, dir, directions);
}
};
Go
func spiralMatrix(m int, n int, head *ListNode) [][]int {
matrix := make([][]int, m)
for i := range matrix {
matrix[i] = make([]int, n)
for j := 0; j < n; j++ {
matrix[i][j] = -1
}
}
directions := [][]int{ {0, 1}, {1, 0}, {0, -1}, {-1, 0} }
sx, sy := 0, 0
matrix[sx][sy] = head.Val
head = head.Next
for d := 0; head != nil; d = (d + 1) % 4 {
for head != nil {
tx, ty := sx + directions[d][0], sy + directions[d][1]
if tx < 0 || tx >= m || ty < 0 || ty >= n || matrix[tx][ty] != -1 {
break
}
sx, sy = tx, ty
matrix[sx][sy] = head.Val
head = head.Next
}
}
return matrix
}
Java
class Solution {
public int[][] spiralMatrix(int m, int n, ListNode head) {
int[][] result = new int[m][n];
int top = 0, left = 0, right = n - 1, bottom = m - 1;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
result[i][j] = -1;
}
}
while (left <= right && top <= bottom) {
for (int i = left; i <= right && head != null; i++) {
result[top][i] = head.val;
head = head.next;
}
top++;
for (int i = top; i <= bottom && head != null; i++) {
result[i][right] = head.val;
head = head.next;
}
right--;
for (int i = right; i >= left && head != null; i--) {
result[bottom][i] = head.val;
head = head.next;
}
bottom--;
for (int i = bottom; i >= top && head != null; i--) {
result[i][left] = head.val;
head = head.next;
}
left++;
}
return result;
}
}