|
1 | 1 | # [Problem 2326: Spiral Matrix IV](https://leetcode.com/problems/spiral-matrix-iv/description/?envType=daily-question)
|
2 | 2 |
|
3 | 3 | ## Initial thoughts (stream-of-consciousness)
|
| 4 | +- Another linked list problem-- yay 🥳! |
| 5 | +- First of all, filling in the "extra" -1s is going to be a pain. So instead of figuring out (directly) which spots are missed, let's just start by initializing a matrix of -1s: `matrix = [[-1] * n for _ in range(m)]` |
| 6 | +- Then...there are two ways of filling stuff in. One option is to keep track of the upper/right-most/lower/left-most "bounds" that we've filled in so far, and then keep looping through until we hit one less than the current limits in the current direction (cycling through top-most left to right --> right-most top to bottom --> bottom-most right to left --> left-most bottom to top). Another option would be to cycle through the same order, but instead of explicitly keeping track of the bounds, just stop when we get to a value that's less than 0. This will "work" because the nodes' values are guaranteed to be greater than or equal to 0 (and less than or equal to 1000, but that doesn't matter here). |
| 7 | +- So the idea could be something like: |
| 8 | + - Start with current position = `matrix[0][0]` and `current_direction = 'right'`. Then initiate `move_right(current_pos)` until either we hit the limits of the matrix along that dimension, or until we encounter a -1, or until we hit the end of the linked list. As we move, we're replacing -1s in the matrix with the values in the linked list, and progressing along the linked list (from node to node). |
| 9 | + - The directions go in order (`['right', 'down', 'left', 'up']`) and we'll need functions to move in each direction |
4 | 10 |
|
5 | 11 | ## Refining the problem, round 2 thoughts
|
| 12 | +- Let's think through how to implement "moving"... |
| 13 | +- I think (after initializing the `matrix` we'll ultimately return), we should iterate through moves in a `while` loop, like this: |
| 14 | +```python |
| 15 | +matrix = [[-1] * n for _ in range(m)] |
| 16 | +pos = [0, 0] |
| 17 | +node = head |
| 18 | +while True: |
| 19 | + for func in [move_right, move_down, move_left, move_up]: |
| 20 | + pos, node = func(pos, node) |
| 21 | + if node is None: |
| 22 | + return matrix |
| 23 | +``` |
| 24 | +- Then we just need to implement each of `move_right`, `move_down`, `move_left`, and `move_up`: |
| 25 | +```python |
| 26 | +def move_right(pos, node): |
| 27 | + while node is not None and pos[1] < n and matrix[pos[0]][pos[1]] == -1: |
| 28 | + matrix[pos[0]][pos[1]] = node.val |
| 29 | + pos[1] += 1 |
| 30 | + node = node.next |
| 31 | + pos[1] -= 1 # undo last move |
| 32 | + pos[0] += 1 # move to next viable position |
| 33 | + return pos, node |
| 34 | + |
| 35 | +def move_down(pos, node): |
| 36 | + while node is not None and pos[0] < m and matrix[pos[0]][pos[1]] == -1: |
| 37 | + matrix[pos[0]][pos[1]] = node.val |
| 38 | + pos[0] += 1 |
| 39 | + node = node.next |
| 40 | + pos[0] -= 1 # undo last move |
| 41 | + pos[1] -= 1 # move to next viable position |
| 42 | + return pos, node |
| 43 | + |
| 44 | +def move_left(pos, node): |
| 45 | + while node is not None and pos[1] >= 0 and matrix[pos[0]][pos[1]] == -1: |
| 46 | + matrix[pos[0]][pos[1]] = node.val |
| 47 | + pos[1] -= 1 |
| 48 | + node = node.next |
| 49 | + pos[1] += 1 # undo last move |
| 50 | + pos[0] -= 1 # move to next viable position |
| 51 | + return pos, node |
| 52 | + |
| 53 | +def move_up(pos, node): |
| 54 | + while node is not None and pos[0] >= 0 and matrix[pos[0]][pos[1]] == -1: |
| 55 | + matrix[pos[0]][pos[1]] = node.val |
| 56 | + pos[0] -= 1 |
| 57 | + node = node.next |
| 58 | + pos[0] += 1 # undo last move |
| 59 | + pos[1] += 1 # move to next viable position |
| 60 | + return pos, node |
| 61 | +``` |
| 62 | +- Ok...let's put it all together! |
6 | 63 |
|
7 | 64 | ## Attempted solution(s)
|
8 | 65 | ```python
|
9 |
| -class Solution: # paste your code here! |
10 |
| - ... |
| 66 | +# Definition for singly-linked list. |
| 67 | +# class ListNode: |
| 68 | +# def __init__(self, val=0, next=None): |
| 69 | +# self.val = val |
| 70 | +# self.next = next |
| 71 | +class Solution: |
| 72 | + def spiralMatrix(self, m: int, n: int, head: Optional[ListNode]) -> List[List[int]]: |
| 73 | + def move_right(pos, node): |
| 74 | + while node is not None and pos[1] < n and matrix[pos[0]][pos[1]] == -1: |
| 75 | + matrix[pos[0]][pos[1]] = node.val |
| 76 | + pos[1] += 1 |
| 77 | + node = node.next |
| 78 | + pos[1] -= 1 # undo last move |
| 79 | + pos[0] += 1 # move to next viable position |
| 80 | + return pos, node |
| 81 | + |
| 82 | + def move_down(pos, node): |
| 83 | + while node is not None and pos[0] < m and matrix[pos[0]][pos[1]] == -1: |
| 84 | + matrix[pos[0]][pos[1]] = node.val |
| 85 | + pos[0] += 1 |
| 86 | + node = node.next |
| 87 | + pos[0] -= 1 # undo last move |
| 88 | + pos[1] -= 1 # move to next viable position |
| 89 | + return pos, node |
| 90 | + |
| 91 | + def move_left(pos, node): |
| 92 | + while node is not None and pos[1] >= 0 and matrix[pos[0]][pos[1]] == -1: |
| 93 | + matrix[pos[0]][pos[1]] = node.val |
| 94 | + pos[1] -= 1 |
| 95 | + node = node.next |
| 96 | + pos[1] += 1 # undo last move |
| 97 | + pos[0] -= 1 # move to next viable position |
| 98 | + return pos, node |
| 99 | + |
| 100 | + def move_up(pos, node): |
| 101 | + while node is not None and pos[0] >= 0 and matrix[pos[0]][pos[1]] == -1: |
| 102 | + matrix[pos[0]][pos[1]] = node.val |
| 103 | + pos[0] -= 1 |
| 104 | + node = node.next |
| 105 | + pos[0] += 1 # undo last move |
| 106 | + pos[1] += 1 # move to next viable position |
| 107 | + return pos, node |
| 108 | + |
| 109 | + matrix = [[-1] * n for _ in range(m)] |
| 110 | + pos = [0, 0] |
| 111 | + node = head |
| 112 | + while True: |
| 113 | + for func in [move_right, move_down, move_left, move_up]: |
| 114 | + pos, node = func(pos, node) |
| 115 | + if node is None: |
| 116 | + return matrix |
11 | 117 | ```
|
| 118 | +- Given test cases pass |
| 119 | +- Let's test some edge cases: |
| 120 | + - Filling in every position in the matrix: |
| 121 | + - `m = 4, n = 5, head = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]`: pass |
| 122 | + - Just a single node, $1 \times 1$ matrix: `m = 1, n = 1, head = [1]`: pass |
| 123 | +- Ok, ready to submit! |
| 124 | + |
| 125 | + |
| 126 | + |
| 127 | +Solved! |
0 commit comments