Great explanation. I tried to come up with my solution prior to watching the video. I used the intuition of concentric squares within the matrix. I traverse one side of each concentric square and perform three swaps for each element . Since only one side of each concentric square is traversed, the number of elements traversed is approximately 1/4(m*n) and since there are 3 swaps for each element the time complexity will be O(3/4 m*n). Using a swap counter, Striver's solution is very close to O(m*n). However, unlike Striver, I do use some extra auxiliary constant space in the form of 4 pairs of co-ordinates which I use to determine the correct placing of the elements during swapping. void rotate(vector& m) { int l = 0; int h = m.size() - 1; pair a, b, c, d; while (l < h) { a = {l,l}; b = {l,h}; c = {h,h}; d = {h,l}; for (int i = l; i < h; i++) { swap (m[a.first][a.second], m[b.first][b.second]); swap (m[a.first][a.second], m[c.first][c.second]); swap (m[a.first][a.second], m[d.first][d.second]); a.second++; b.first++; c.second--; d.first--; } l++; h--; } }
Thanks. We can further improve by not using loop for reversing of row in optimal instead just use reverse after j loop is finished like this: for(int i = 0; i < n; i++) { for(int j = i + 1; j < n; j++) { swap(mat[i][j], mat[j][i]); } reverse(mat[i].begin(), mat[i].end()); }
I did this optimal solution on my own, then came to see the solution video, this sheet building my confidence and skills little by little. (Rikon was my childhood friend. He worked for you some days back. No wonder why he praised you so much.)
I used the idea of concentric squares to solve the problem. Say, n = 6. Now the square will be of 3X3 size. You can draw a matrix to see how the outer square is of length = 6, inside it there's a square of side = 4 and inside it there's another square of side = 2. Basically each inside square is of 2 units lesser length then its outer square. We traverse from outside to inside and rotate each square one by one. For rotation, we traverse the upper side of the square and use 3 swaps for each grid. Also, the traversal is done till 2nd last grid because if you do the dry run, you'll notice that the last grid is already swapped in the first step, i.e., the corners are common between 2 given sides. The most difficult part is to deduce the co-ordinates for the replacing element. Imagine a square which you're traversing on its top side. Now, the top left element will be replaced by bottom left, bottom left by bottom right, bottom right by top right and top right by top left. It's hard to explain in a comment how I arrived at the co-ordinates but if someone wants to try this out, instead of swapping element by element, first try swapping row by row. I've attached codes for both. Basically, store the upper side of square in a temp array then replace top row with left column, replace left column with bottom row and so on. Once you understand how that's working, the co-ordinates for element by element swap is same but using lesser extra space. If someone needs a video explanation, do reply and I'll try to post a video explaining the same. // Swapping row by row: for (int i = 0; i < n/2; i++) { vector temp; for (int j = i; j < m-i; j++) temp.push_back(mat[i][j]); for (int j = m-i-1; j >= i; j--) mat[i][j] = mat[n-1-j][i]; for (int j = m-i-1; j >= i; j--) mat[n-1-j][i] = mat[n-1-i][m-1-j]; for (int j = m-i-1; j >= i; j--) mat[n-1-i][m-1-j] = mat[j][m-1-i]; for (int j = m-i-1; j >= i; j--) mat[j][m-1-i] = temp[j-i]; } // Swapping element by element int len = mat.size(); for (int i = 0; i < len/2; i++) { for (int j = i; j < (len-i-1); j++) { int temp = mat[i][j]; mat[i][j] = mat[len-1-j][i]; mat[len-1-j][i] = mat[len-1-i][len-1-j]; mat[len-1-i][len-1-j] = mat[j][len-1-i]; mat[j][len-1-i] = temp; } }
Thanks a lot bhaiya. This time I must say you are on fire. Your explaining capability is next level, bez I had problems in understanding the matrix(index and all). But Now super clear. OP Striver Guru 🔥🔥🔥🔥
#Free Education For All.. # Bhishma Pitamah of DSA...You could have earned in lacs by putting it as paid couses on udamey or any other elaerning portals, but you decided to make it free...it requires a greate sacrifice and a feeling of giving back to community, there might be very few peope in world who does this...."विद्या का दान ही सर्वोत्तम दान होता है" Hats Off to you man, Salute from 10+ yrs exp guy from BLR, India.
now I understood why bhai chose c++ over java because u have to write so many function in java but in c++ u have stl :( . But bro i understood the question thanku :b
an approach i came up with, if you need to rotate clockwise, just swap elements at each layer anticlockwise void rotate(vector& matrix) { int n = matrix.size(); for(int i=0; i
9:54 We do transpose not because we need to convert rows into column. If we have a another matrix to store then we can do it directly instead of two steps. we do it so that we can swap elements. you can't do it directly. so do the extra step
How you elaborate on the problem and solution is unique to any other free content I have gone through. I'll surely gonna recommend your channel if somebody asks.
hi, the solution provided in the sheet for java doesn't follow the same explanation, the logic is bit changed in it. Here, is the code following the explanation: class Solution { public void rotate(int[][] matrix) { int n = matrix.length, m = matrix[0].length; //Transpose for(int i =0; i
Hi bro! I came across this problem and the first two operations on my mind were transpose and reverse. As the problem requried it to be solved in O(1) space, I carefully examined if the sequence of these operations made any signifcant changes to the performance. What I did was to reverse the matrix (row-wise) first, then take a transpose. The first operation used n/2 iterations (for optimal reversing). The second operation used n*(n+1)/2 iterations (for optimal transpose). So the total number of iterations with optimization: (n(n + 1) + n)/2 = O(n^2 + n) = O(n^2) With transpose first and then reverse each row: (n(n+1) + n^2)/2 = O(n^2 + n^2) = O(n^2) It doesn't make a difference as our PCs are blazzingly fast, but I found it neat :) Thanks a lot! This series is amazing!♥♥
Java Code: ```class Solution { public void rotate(int[][] matrix) { int n = matrix.length; // Transpose of Matrix for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { int temp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = temp; } } // Reverse each row for (int i = 0; i < n; i++) { int left = 0, right = n - 1; while (left < right) { int temp = matrix[i][left]; matrix[i][left] = matrix[i][right]; matrix[i][right] = temp; left++; right--; } } } }```
this is how I wrote the transpose code for(int i=0; i< n ; i++){ for(int j=i; j < n; j++){ swap(matrix[i][j], matrix[j][i]); } } which is less confusing
bro this code is not optimal, because it this code u will traverse through all elements, and the code in the video is not traversing the diagonal element which reduce the time complexity
I thought that too. For the first loop, we still have to go through all of the rows except last one, which would be O(n). Now, for each row you go through, you will go through n - (i + 1) columns, which theoretically means you go through the later half of our matrix. This is why it is calculated as n/2. Then, when we loop through the rows and reverse them, we say we go through n rows and for each row we have to go loop through it to reverse them, which with the algorithm provided by Striver, it takes n/2. So, the answer would be in fact O(n * n/2) + O(n * n/2), which in simpler terms is O(n^2/2).