mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-27 15:41:16 +08:00
Add square matrix rotation in-place algorithm.
This commit is contained in:
parent
17ad4dc4d1
commit
75133592bb
@ -116,6 +116,7 @@ a set of rules that precisely define a sequence of operations.
|
|||||||
* `B` [Tower of Hanoi](src/algorithms/uncategorized/hanoi-tower)
|
* `B` [Tower of Hanoi](src/algorithms/uncategorized/hanoi-tower)
|
||||||
* `A` [N-Queens Problem](src/algorithms/uncategorized/n-queens)
|
* `A` [N-Queens Problem](src/algorithms/uncategorized/n-queens)
|
||||||
* `A` [Knight's Tour](src/algorithms/uncategorized/knight-tour)
|
* `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
|
### Algorithms by Paradigm
|
||||||
|
|
||||||
|
@ -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/)
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user