Skip to content

Commit 304da07

Browse files
885. Spiral Matrix III
1 parent 1dac00e commit 304da07

File tree

9 files changed

+304
-0
lines changed

9 files changed

+304
-0
lines changed
3.51 KB
Loading
7.86 KB
Loading
27.3 KB
Loading
Loading
+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
class Solution
2+
{
3+
public:
4+
// Définition des directions de mouvement : droite, bas, gauche, haut
5+
vector<vector<int>> dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
6+
7+
// Fonction pour ajuster les coordonnées lorsqu'on dépasse les limites sur les axes positif
8+
void jumpA(int &i, int &curr, int length)
9+
{
10+
// Si on sort du côté négatif, on ramène curr à -1 et ajuste l'indice i
11+
if (curr < 0)
12+
{
13+
i += abs(curr) - 1;
14+
curr = -1;
15+
}
16+
// Sinon, on avance curr au maximum permis par la longueur restante et ajuste i
17+
else
18+
{
19+
curr += length - i - 1;
20+
i = length;
21+
}
22+
}
23+
24+
// Fonction pour ajuster les coordonnées lorsqu'on dépasse les limites sur les axes négatif
25+
void jumpB(int &i, int &curr, int length, int n)
26+
{
27+
// Si curr dépasse la limite supérieure, on l'ajuste à la limite et ajuste l'indice i
28+
if (curr >= n)
29+
{
30+
i += curr - n;
31+
curr = n;
32+
}
33+
// Sinon, on recule curr de la longueur restante et ajuste i
34+
else
35+
{
36+
curr -= length - i - 1;
37+
i = length;
38+
}
39+
}
40+
41+
// Génère une matrice parcourue en spirale à partir d'une position de départ
42+
vector<vector<int>> spiralMatrixIII(int rows, int cols, int rStart, int cStart)
43+
{
44+
// Calcul de la taille totale de la matrice
45+
int size = rows * cols;
46+
47+
// Initialisation de la matrice de résultat avec la position de départ
48+
vector<vector<int>> ans = {{rStart, cStart}};
49+
50+
// Variables pour garder la trace de la position actuelle
51+
int currR = rStart;
52+
int currC = cStart;
53+
// Variable pour indiquer la direction actuelle
54+
int d = 0;
55+
56+
// Boucle jusqu'à ce que toutes les positions valides soient visitées
57+
while (ans.size() != size)
58+
{
59+
// Détermine la longueur de la prochaine étape dans la direction courante
60+
int length = (d / 2) + 1;
61+
// Sélectionne la direction actuelle (0: droite, 1: bas, 2: gauche, 3: haut)
62+
int curr = d % 4;
63+
64+
// Avance dans la direction choisie pour la longueur déterminée
65+
for (int i = 0; i < length; i++)
66+
{
67+
currR += dir[curr][0]; // Mise à jour de la ligne courante
68+
currC += dir[curr][1]; // Mise à jour de la colonne courante
69+
70+
// Si la nouvelle position est à l'intérieur de la matrice, l'ajoute au résultat
71+
if (currR >= 0 && currR < rows && currC >= 0 && currC < cols)
72+
{
73+
ans.push_back({currR, currC});
74+
}
75+
// Si la position dépasse les limites elle est ajusté
76+
else
77+
{
78+
if (curr == 0)
79+
{
80+
jumpA(i, currC, length); // Ajuste la colonne en cas de dépassement à droite
81+
}
82+
else if (curr == 1)
83+
{
84+
jumpA(i, currR, length); // Ajuste la ligne en cas de dépassement en bas
85+
}
86+
else if (curr == 2)
87+
{
88+
jumpB(i, currC, length, cols); // Ajuste la colonne en cas de dépassement à gauche
89+
}
90+
else
91+
{
92+
jumpB(i, currR, length, rows); // Ajuste la ligne en cas de dépassement en haut
93+
}
94+
}
95+
}
96+
97+
// Passe à la direction suivante
98+
d++;
99+
}
100+
101+
return ans;
102+
}
103+
};
+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# 885. Spiral Matrix III
2+
3+
## Énoncé
4+
5+
Vous commencez à la cellule `(rStart, cStart)` d'une grille de dimensions `rows x cols`, face à l'est. Le coin nord-ouest se trouve à la première ligne et la première colonne de la grille, et le coin sud-est se trouve à la dernière ligne et colonne.
6+
7+
Vous allez marcher en spirale dans le sens des aiguilles d'une montre pour visiter chaque position de cette grille. Chaque fois que vous sortez des limites de la grille, vous continuez votre marche en dehors de la grille (mais il est possible de revenir plus tard à la frontière de la grille). Finalement, vous atteignez toutes les `rows * cols` cases de la grille.
8+
9+
Retournez un tableau de coordonnées représentant les positions de la grille dans l'ordre dans lequel vous les avez visitées.
10+
11+
## Exemple
12+
13+
**Exemple 1:**
14+
15+
<img src="./imgs/img1.png"/>
16+
17+
**Input:** rows = 1, cols = 4, rStart = 0, cStart = 0
18+
**Output:** [[0,0],[0,1],[0,2],[0,3]]
19+
20+
**Exemple 2:**
21+
22+
<img src="./imgs/img2.png"/>
23+
24+
**Input:** rows = 5, cols = 6, rStart = 1, cStart = 4
25+
**Output:** [[1,4],[1,5],[2,5],[2,4],[2,3],[1,3],[0,3],[0,4],[0,5],[3,5],[3,4],[3,3],[3,2],[2,2],[1,2],[0,2],[4,5],[4,4],[4,3],[4,2],[4,1],[3,1],[2,1],[1,1],[0,1],[4,0],[3,0],[2,0],[1,0],[0,0]]
26+
27+
## Contraintes
28+
29+
`1 <= rows, cols <= 100`
30+
`0 <= rStart < rows`
31+
`0 <= cStart < cols`
32+
33+
## Note personnelle
34+
35+
### Approche 1: Simulation
36+
37+
En examinant les illustrations de l'exemple, on constate qu'à chaque changement de direction, la longueur du déplacement sur l'axe concerné augmente tous les deux mouvements.
38+
39+
Cela crée une séquence de longueurs comme suit : [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ...].
40+
41+
L'algorithme simule simplement cette séquence de longueurs tout en parcourant la matrice. Si la position actuelle se trouve dans les limites de la matrice, on ajoute ses coordonnées à notre tableau de réponse.
42+
43+
```cpp
44+
// Directions correspondantes aux mouvements dans l'ordre : droite, bas, gauche, haut
45+
vector<vector<int>> dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
46+
47+
vector<vector<int>> spiralMatrixIII(int rows, int cols, int rStart, int cStart) {
48+
// Calcul de la taille totale de la matrice
49+
int size = rows * cols;
50+
51+
// Initialisation de la matrice de résultat avec la position de départ
52+
vector<vector<int>> ans = {{rStart, cStart}};
53+
54+
// Variables pour garder la trace de la position actuelle
55+
int currR = rStart;
56+
int currC = cStart;
57+
// Variable pour indiquer la direction actuelle
58+
int d = 0;
59+
60+
// Boucle jusqu'à ce que toutes les positions valides soient visitées
61+
while (ans.size() != size) {
62+
// Détermine la longueur de la prochaine étape dans la direction courante
63+
int length = (d / 2) + 1;
64+
// Sélectionne la direction actuelle (0: droite, 1: bas, 2: gauche, 3: haut)
65+
int curr = d % 4;
66+
67+
// Avance dans la direction choisie pour la longueur déterminée
68+
for(int i = 0; i < length; i++){
69+
currR += dir[curr][0]; // Mise à jour de la ligne courante
70+
currC += dir[curr][1]; // Mise à jour de la colonne courante
71+
72+
// Vérifie si la nouvelle position est dans les limites de la matrice
73+
if (currR >= 0 && currR < rows && currC >= 0 && currC < cols) {
74+
// Si c'est le cas, ajoute cette position à la liste des résultats
75+
ans.push_back({currR, currC});
76+
}
77+
}
78+
79+
// Passe à la direction suivante
80+
d++;
81+
}
82+
83+
return ans;
84+
}
85+
```
86+
87+
- Complexité Temporelle: `O(m * n)`.
88+
- Complexité Spatiale: `O(m * n)`.
89+
90+
### Optimisation
91+
92+
Pour améliorer l'approche précédente, l'idée est de sauter les positions invalides, ce qui permet de réduire le nombre d'itérations.
93+
94+
Il existe quatre types de sauts possibles :
95+
96+
- Lorsque l'on incrémente la position sur un axe:
97+
- Si la position actuelle est inférieure à 0, on saute jusqu'à -1.
98+
- Si la position actuelle est supérieure ou égale à 0, on saute jusqu'à avoir parcouru `length` cases au total.
99+
- Lorsque l'on décrémente la position sur un axe:
100+
- Si la position actuelle dépasse la dernière case de l'axe, on saute jusqu'à cette dernière case.
101+
- Si la position actuelle est inférieure à la dernière case de l'axe, on saute jusqu'à avoir parcouru `length` cases au total.
102+
103+
Ici, `length` représente le nombre de cases à parcourir sur l'axe en cours.
104+
105+
```cpp
106+
// Définition des directions de mouvement : droite, bas, gauche, haut
107+
vector<vector<int>> dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
108+
109+
// Fonction pour ajuster les coordonnées lorsqu'on dépasse les limites sur les axes positif
110+
void jumpA(int &i, int &curr, int length){
111+
// Si on sort du côté négatif, on ramène curr à -1 et ajuste l'indice i
112+
if(curr < 0){
113+
i += abs(curr) - 1;
114+
curr = -1;
115+
}
116+
// Sinon, on avance curr au maximum permis par la longueur restante et ajuste i
117+
else{
118+
curr += length - i - 1;
119+
i = length;
120+
}
121+
}
122+
123+
// Fonction pour ajuster les coordonnées lorsqu'on dépasse les limites sur les axes négatif
124+
void jumpB(int &i, int &curr, int length, int n){
125+
// Si curr dépasse la limite supérieure, on l'ajuste à la limite et ajuste l'indice i
126+
if(curr >= n){
127+
i += curr - n;
128+
curr = n;
129+
}
130+
// Sinon, on recule curr de la longueur restante et ajuste i
131+
else{
132+
curr -= length - i - 1;
133+
i = length;
134+
}
135+
}
136+
137+
// Génère une matrice parcourue en spirale à partir d'une position de départ
138+
vector<vector<int>> spiralMatrixIII(int rows, int cols, int rStart, int cStart) {
139+
// Calcul de la taille totale de la matrice
140+
int size = rows * cols;
141+
142+
// Initialisation de la matrice de résultat avec la position de départ
143+
vector<vector<int>> ans = {{rStart, cStart}};
144+
145+
// Variables pour garder la trace de la position actuelle
146+
int currR = rStart;
147+
int currC = cStart;
148+
// Variable pour indiquer la direction actuelle
149+
int d = 0;
150+
151+
// Boucle jusqu'à ce que toutes les positions valides soient visitées
152+
while (ans.size() != size) {
153+
// Détermine la longueur de la prochaine étape dans la direction courante
154+
int length = (d / 2) + 1;
155+
// Sélectionne la direction actuelle (0: droite, 1: bas, 2: gauche, 3: haut)
156+
int curr = d % 4;
157+
158+
// Avance dans la direction choisie pour la longueur déterminée
159+
for(int i = 0; i < length; i++){
160+
currR += dir[curr][0]; // Mise à jour de la ligne courante
161+
currC += dir[curr][1]; // Mise à jour de la colonne courante
162+
163+
// Si la nouvelle position est à l'intérieur de la matrice, l'ajoute au résultat
164+
if (currR >= 0 && currR < rows && currC >= 0 && currC < cols) {
165+
ans.push_back({currR, currC});
166+
}
167+
// Si la position dépasse les limites elle est ajusté
168+
else {
169+
if(curr == 0){
170+
jumpA(i, currC, length); // Ajuste la colonne en cas de dépassement à droite
171+
}
172+
else if(curr == 1){
173+
jumpA(i, currR, length); // Ajuste la ligne en cas de dépassement en bas
174+
}
175+
else if(curr == 2){
176+
jumpB(i, currC, length, cols); // Ajuste la colonne en cas de dépassement à gauche
177+
}
178+
else {
179+
jumpB(i, currR, length, rows); // Ajuste la ligne en cas de dépassement en haut
180+
}
181+
}
182+
}
183+
184+
// Passe à la direction suivante
185+
d++;
186+
}
187+
188+
return ans;
189+
}
190+
```
191+
192+
- Complexité Temporelle: `O(m * n)`.
193+
- Complexité Spatiale: `O(m * n)`.
194+
195+
Cette optimisation n'affecte pas la complexité temporelle, cependant elle permet de réduire de manière significative le nombre d'itérations lorsque le point de départ est proche des bords de la matrice.
196+
197+
<img src="./imgs/runtime.png"/>
198+
<img src="./imgs/memory.png"/>

skills/array.md

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ Illustration d'un tableau a une dimension:
9696
| [713. Subarray Product Less Than K](../Probleme/0713.%20Subarray%20Product%20Less%20Than%20K/) | [`Array`](./array.md), [`Sliding Window`](./sliding_window.md) | 27-03-2024 |
9797
| [735. Asteroid Collision](../Probleme/0735.%20Asteroid%20Collision/) | [`Array`](./array.md), [`Stack`](./stack.md), [`Simulation`](./simulation.md) | 18-04-2024 |
9898
| [752. Open the Lock](../Probleme/0752.%20Open%20the%20Lock/) | [`Array`](./array.md), [`Hash Table`](./hash_table.md), [`String`](./string.md), [`Breadth-First Search`](./bfs.md) | 22-04-2024 |
99+
| [885. Spiral Matrix III](../Probleme/0885.%20Spiral%20Matrix%20III/) | [`Array`](./array.md), [`Matrix`](./matrix.md), [`Simulation`](./simulation.md) | 09-08-2024 |
99100
| [934. Shortest Bridge](../Probleme/0934.%20Shortest%20Bridge/) | [`Array`](./array.md), [`Depth-First Search`](./dfs.md), [`Breadth-First Search`](./bfs.md), [`Matrix`](./matrix.md) | 29-03-2024 |
100101
| [948. Bag of Tokens](../Probleme/0948.%20Bag%20of%20Tokens/) | [`Array`](./array.md), [`Greedy`](./greedy.md), [`Two Pointers`](./two_pointers.md), [`Sorting`](./sorting.md) | 04-03-2024 |
101102
| [1052. Grumpy Bookstore Owner](../Probleme/1052.%20Grumpy%20Bookstore%20Owner/) | [`Array`](./array.md), [`Sliding Window`](./sliding_window.md) | 22-06-2024 |

skills/matrix.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Une **Matrice** est essentiellement un tableau de nombres organisé en lignes et
2424
| [200. Number of Islands](../Probleme/0200.%20Number%20of%20Islands/) | [`Array`](./array.md), [`Depth-First Search`](./dfs.md), [`Breadth-First Search`](./bfs.md), [`Union Find`](./union_find.md), [`Matrix`](./matrix.md) | 19-04-2024 |
2525
| [289. Game of Life](../Probleme/0289.%20Game%20of%20Life/) | [`Array`](./array.md), [`Matrix`](./matrix.md), [`Simulation`](./simulation.md) | 06-03-2024 |
2626
| [542. 01 Matrix](../Probleme/0542.%2001%20Matrix/) | [`Array`](./array.md), [`Dynamic Programming`](./dp.md), [`Breadth-First Search`](./bfs.md), [`Matrix`](./matrix.md) | 27-04-2024 |
27+
| [885. Spiral Matrix III](../Probleme/0885.%20Spiral%20Matrix%20III/) | [`Array`](./array.md), [`Matrix`](./matrix.md), [`Simulation`](./simulation.md) | 09-08-2024 |
2728
| [934. Shortest Bridge](../Probleme/0934.%20Shortest%20Bridge/) | [`Array`](./array.md), [`Depth-First Search`](./dfs.md), [`Breadth-First Search`](./bfs.md), [`Matrix`](./matrix.md) | 29-03-2024 |
2829
| [2326. Spiral Matrix IV](../Probleme/2326.%20Spiral%20Matrix%20IV/) | [`Array`](./array.md), [`Matrix`](./matrix.md), [`Simulation`](./simulation.md), [`Linked List`](./linked_list.md) | 09-08-2024 |
2930

skills/simulation.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
| [54. Spiral Matrix](../Probleme/0054.%20Spiral%20Matrix/) | [`Array`](./array.md), [`Matrix`](./matrix.md), [`Simulation`](./simulation.md) | 09-08-2024 |
1818
| [59. Spiral Matrix II](../Probleme/0059.%20Spiral%20Matrix%20II/) | [`Array`](./array.md), [`Matrix`](./matrix.md), [`Simulation`](./simulation.md) | 09-08-2024 |
1919
| [289. Game of Life](../Probleme/0289.%20Game%20of%20Life/) | [`Array`](./array.md), [`Matrix`](./matrix.md), [`Simulation`](./simulation.md) | 06-03-2024 |
20+
| [885. Spiral Matrix III](../Probleme/0885.%20Spiral%20Matrix%20III/) | [`Array`](./array.md), [`Matrix`](./matrix.md), [`Simulation`](./simulation.md) | 09-08-2024 |
2021
| [735. Asteroid Collision](../Probleme/0735.%20Asteroid%20Collision/) | [`Array`](./array.md), [`Stack`](./stack.md), [`Simulation`](./simulation.md) | 18-04-2024 |
2122
| [1701. Average Waiting Time](../Probleme/1701.%20Average%20Waiting%20Time/) | [`Array`](./array.md), [`Simulation`](./simulation.md) | 09-07-2024 |
2223
| [1823. Find the Winner of the Circular Game](../Probleme/1823.%20Find%20the%20Winner%20of%20the%20Circular%20Game/) | [`Array`](./array.md), [`Math`](./math.md), [`Recursion`](./recursion.md), [`Queue`](./queue.md), [`Simulation`](./simulation.md) | 09-07-2024 |

0 commit comments

Comments
 (0)