Skip to content

Commit

Permalink
Add square matrix rotation in-place algorithm.
Browse files Browse the repository at this point in the history
  • Loading branch information
trekhleb committed Jul 6, 2018
1 parent 17ad4dc commit 7513359
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ a set of rules that precisely define a sequence of operations.
* `B` [Tower of Hanoi](src/algorithms/uncategorized/hanoi-tower)
* `A` [N-Queens Problem](src/algorithms/uncategorized/n-queens)
* `A` [Knight's Tour](src/algorithms/uncategorized/knight-tour)
* `B` [Square Matrix Rotation](src/algorithms/uncategorized/square-matrix-rotation) - in-place algorithm

### Algorithms by Paradigm

Expand Down
90 changes: 90 additions & 0 deletions src/algorithms/uncategorized/square-matrix-rotation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Square Matrix In-Place Rotation

## The Problem

You are given an `n x n` 2D matrix (representing an image).
Rotate the matrix by `90` degrees (clockwise).

**Note**

You have to rotate the image **in-place**, which means you
have to modify the input 2D matrix directly. **DO NOT** allocate
another 2D matrix and do the rotation.

## Examples

**Example #1**

Given input matrix:

```
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
```

Rotate the input matrix in-place such that it becomes:

```
[
[7, 4, 1],
[8, 5, 2],
[9, 6, 3],
]
```

**Example #2**

Given input matrix:

```
[
[5, 1, 9, 11],
[2, 4, 8, 10],
[13, 3, 6, 7],
[15, 14, 12, 16],
]
```

Rotate the input matrix in-place such that it becomes:

```
[
[15, 13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7, 10, 11],
]
```

## Algorithm

We would need to do two reflections of the matrix:

- reflect vertically
- reflect diagonally from bottom-left to top-right

Or we also could Furthermore, you can reflect diagonally
top-left/bottom-right and reflect horizontally.

A common question is how do you even figure out what kind
of reflections to do? Simply rip a square piece of paper,
write a random word on it so you know its rotation. Then,
flip the square piece of paper around until you figure out
how to come to the solution.

Here is an example of how first line may be rotated using
diagonal top-right/bottom-left rotation along with horizontal
rotation.

```
A B C A - - . . A
/ / --> B - - --> . . B
/ . . C - - . . C
```

## References

- [LeetCode](https://leetcode.com/problems/rotate-image/description/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import squareMatrixRotation from '../squareMatrixRotation';

describe('squareMatrixRotation', () => {
it('should rotate matrix #0 in-place', () => {
const matrix = [[1]];

const rotatedMatrix = [[1]];

expect(squareMatrixRotation(matrix)).toEqual(rotatedMatrix);
});

it('should rotate matrix #1 in-place', () => {
const matrix = [
[1, 2],
[3, 4],
];

const rotatedMatrix = [
[3, 1],
[4, 2],
];

expect(squareMatrixRotation(matrix)).toEqual(rotatedMatrix);
});

it('should rotate matrix #2 in-place', () => {
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];

const rotatedMatrix = [
[7, 4, 1],
[8, 5, 2],
[9, 6, 3],
];

expect(squareMatrixRotation(matrix)).toEqual(rotatedMatrix);
});

it('should rotate matrix #3 in-place', () => {
const matrix = [
[5, 1, 9, 11],
[2, 4, 8, 10],
[13, 3, 6, 7],
[15, 14, 12, 16],
];

const rotatedMatrix = [
[15, 13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7, 10, 11],
];

expect(squareMatrixRotation(matrix)).toEqual(rotatedMatrix);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @param {*[][]} originalMatrix
* @return {*[][]}
*/
export default function squareMatrixRotation(originalMatrix) {
const matrix = originalMatrix.slice();

// Do top-right/bottom-left diagonal reflection of the matrix.
for (let rowIndex = 0; rowIndex < matrix.length; rowIndex += 1) {
for (let columnIndex = rowIndex + 1; columnIndex < matrix.length; columnIndex += 1) {
const tmp = matrix[columnIndex][rowIndex];
matrix[columnIndex][rowIndex] = matrix[rowIndex][columnIndex];
matrix[rowIndex][columnIndex] = tmp;
}
}

// Do horizontal reflection of the matrix.
for (let rowIndex = 0; rowIndex < matrix.length; rowIndex += 1) {
for (let columnIndex = 0; columnIndex < matrix.length / 2; columnIndex += 1) {
const mirrorColumnIndex = matrix.length - columnIndex - 1;
const tmp = matrix[rowIndex][mirrorColumnIndex];
matrix[rowIndex][mirrorColumnIndex] = matrix[rowIndex][columnIndex];
matrix[rowIndex][columnIndex] = tmp;
}
}

return matrix;
}

0 comments on commit 7513359

Please sign in to comment.