# 54. Spiral Matrix

🟧 Medium

Given an `m x n` `matrix`, return *all elements of the `matrix` in spiral order.*

## Example 1

![matrix](https://assets.leetcode.com/uploads/2020/11/13/spiral1.jpg)

> **Input**: matrix = \[\[1,2,3],\[4,5,6],\[7,8,9]]\
> **Output**: \[1,2,3,6,9,8,7,4,5]

## Example 2

![matrix](https://assets.leetcode.com/uploads/2020/11/13/spiral.jpg)

> **Input**: matrix = \[\[1,2,3,4],\[5,6,7,8],\[9,10,11,12]]\
> **Output**: \[1,2,3,4,8,12,11,10,9,5,6,7]

## Constraints

* `m == matrix.length`
* `n == matrix[i].length`
* `1 <= m, n <= 10`
* `-100 <= matrix[i][j] <= 100`

## Hint 1

> Well for some problems, the best way really is to come up with some algorithms for simulation. Basically, you need to simulate what the problem asks us to do.

## Hint 2

> We go boundary by boundary and move inwards. That is the essential operation. First row, last column, last row, first column, and then we move inwards by 1 and repeat. That's all. That is all the simulation that we need.

## Hint 3

> Think about when you want to switch the progress on one of the indexes. If you progress on i out of \[i, j], you'll shift in the same column. Similarly, by changing values for j, you'd be shifting in the same row. Also, keep track of the end of a boundary so that you can move inwards and then keep repeating. It's always best to simulate edge cases like a single column or a single row to see if anything breaks or not.

## Solution

My Solution

```go
func spiralOrder(matrix [][]int) []int {
    m, n := len(matrix), len(matrix[0])
    l, r, up, down := 0, n-1, 0, m-1
    nums := make([]int, 0, m*n)

    for {
        for i:= l; i<= r; i++ {
            nums = append(nums, matrix[up][i])
        }
        up++
        if up > down {
            break
        }

        for i:=up; i<=down; i++ {
            nums = append(nums, matrix[i][r])
        }
        r--
        if l>r {
            break
        }

        for i:=r; i>=l; i-- {
            nums = append(nums, matrix[down][i])
        }
        down--
        if down < up {
            break
        }

        for i:= down; i>=up; i-- {
            nums = append(nums, matrix[i][l])
        }
        l++
        if l > r {
            break
        }
    }

    return nums
}
```

Optimal solution

```go
func spiralOrder(matrix [][]int) []int {
    if len(matrix) == 0 {
        return []int{}
    }

    top, bottom := 0, len(matrix)-1
    left, right := 0, len(matrix[0])-1
    result := []int{}

    for top <= bottom && left <= right {
        // Yuqoridan o‘ngga
        for i := left; i <= right; i++ {
            result = append(result, matrix[top][i])
        }
        top++

        // O‘ngdan pastga
        for i := top; i <= bottom; i++ {
            result = append(result, matrix[i][right])
        }
        right--

        // Pastdan chapga
        if top <= bottom {
            for i := right; i >= left; i-- {
                result = append(result, matrix[bottom][i])
            }
            bottom--
        }

        // Chapdan yuqoriga
        if left <= right {
            for i := bottom; i >= top; i-- {
                result = append(result, matrix[i][left])
            }
            left++
        }
    }

    return result
}
```

![result](/files/JUJqzCWXZ7YS8cy1OQvw)

Leetcode: [link](https://leetcode.com/problems/spiral-matrix/description)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://leetcode.realtemirov.uz/problems/54.-spiral-matrix.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
