Several questions about the simulation, the typical one is to follow specific rules to go through each element of the matrix.
There are several imporant concepts, lets using 885 as an example.
boundry position, the boundry position can change dynamically during the simulation for each iteration, it labels the min and max value the i and j can be. One simple protocol to change the boundy is that for example, when we use the right boundry, such as move j till the maxC, then after this operation, we then shink the right bounudry. Then we can do similar operations for other boundries. The only difference is that we put the updating of minR bounudy at the beginning of the while iteration, since we input the first element out of the while loop, we execute it one more time.
Wall, the wall position is the outter layer of the grid, be careful about it, when the grid is fixed, the wall is fixed, the boundy can be overlap with the wall. In this case, we might need some special operations, such as not inserting the element into the path.
Do not mix the wall and boundry, they are two different concepts, the wall is fixed and the boundry can change dynamically according to the requirments from of the question.
2d vector for iterating the 4 direaction. In order to make the code simple, the good practice is to maintain a 2d vector to control how the x and y move, this is an exmaple, we just need to go through these 2d vector gradually to control the movement of the current element.
Double check the position of (0,0). In most of the case, we set the upper left position as 0,0 which match with our habit to write a matrix in math, we set the first row as 0, and if we have second row, it is 1. Be careful when we output associated reuslts for visualization, in that case, or in the commonly used coordinates system, the left bottom corner is usualy set as 0,0. Which is a common practice when we set coordinates. So be careful about it when we want to visualize sth. In that case, the first row in the output data might be actually the last row in the original data!!! Be careful about this difference.
Some of these questions can also be considered from perspective of the two pointers. Since x and y are ensentially two index of iterating. Instead of going through every combination of x and y, we just select proper combination of x and y and choose suitable elements.
- Another tip is that be careful to decide when to break the loop, we need to check weather go out of the loop after move right or move down. If we do not move down, there is logic error when we move from right to left, this might cause that we insert a repeated element.
int dirs[][2]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; |
- Another small but tricky techniques is to consider the sequence of move and record and how to use loop to divide it. We might need to consider first or last element separately. Considering this loop while (i<maxC) {record i; i++} the second loop is while (i<maxC) {i++; record i}. The difference is that for first element, in the while loop, the case of i==maxC will not be recorded, we might need to consider last element separately. For the second case, the i==maxC will be recorded, we might need to process first element separately before the while loop. Or we need to update the loop condition for the second case, to let the i<=maxC
54 Spiral Matrix
There is a workable solution, but not good, a little bit messy, the special case contains one row and one column.
The core issue is that for some cases, we did not execute all 4 move before exiting
This is the code that consider the move in firstly and then insert, we need to consider some cases before the for loop
class Solution { |
59 Spiral Matrix II
After getting familir with all tips and concepts discussed in this blog, we can solve the code and write workable code really quickly
class Solution { |
885 Spiral Matrix III
This question is a little bit tricky for the boundry case, the key point is to decide wheather the right up conner belongs to the horizental line or vertical line.
class Solution { |
Another solution is to update metadata firstly and then move, it assumes that the element at the right up corner is the one that need to be pushed through vertival line. Maybe I am more comfortable with this type of coding style. Becareful to only push the element into the path when it is not at the wall. We basically put an ghost region among the matrix. When maxC/maxR and minC/minR go to the ghost region, it does not change further. When pointer goes to the ghost region, it will not be pushed into the path.
class Solution { |
2326 Spiral Matrix IV
This can be solved quickly based on previous one, just following the same method and adding a small trick for getting values from the nodelist
/** |