mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-26 07:01:18 +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)
|
||||
* `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
|
||||
|
||||
|
@ -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