The trick is not to think of the matrix as a series of layers to be traversed. That works, but it's harder, cognitively speaking. Keeping nStart and nEnd lets you imagine yourself pinching off individual rows and columns one at a time. You iterate over that nx1 or 1xn array, then put it back.

```
public class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int nStart = 0;
int nEnd = n;
int counter = 1;
while (nStart < nEnd){
for(int i =nStart; i < nEnd; i++) matrix[nStart][i] = counter++; //Right
for(int i = nStart + 1; i < nEnd; i++) matrix[i][nEnd - 1] = counter++; //Down
for(int i = nEnd - 2; i >= nStart; i--) matrix[nEnd - 1][i] = counter++; //Left
for(int i = nEnd - 2; i > nStart; i--) matrix[i][nStart] = counter++; //Up
nEnd--;
nStart++;
}
return matrix;
}
}
```