简体   繁体   中英

Rotate image - leetcode

Apologies if I am asking something stupid (I'm pretty new to coding), but I didn't manage to find a clear explanation to my doubt. I came across the following problem on leetcode:

You are given an nxn 2D matrix representing an image, rotate the image by 90 degrees (clockwise). 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. Example: Input: matrix = [[1,2,3],[4,5,6],[7,8,9]] Output: [[7,4,1],[8,5,2],[9,6,3]]

My solution is:

class Solution:
    def rotate(self, matrix):
        l = len(matrix)

        clockwise_nums = [matrix[j][i] for i in range(l) for j in range(l - 1, -1, -1)]

        final_array = [clockwise_nums[i:i + l] for i in range(0, len(clockwise_nums), l)]

        return final_array

The sheer execution (matrix rotation) works but this is not accepted as it's not in-place. But I don't really get what that means. Do you think my approach is way off here and I should try something different? Or is there a way to adjust my solution (was quite happy that I came up with a way to rotate the matrix)? Also, any tip about in-place algorithm would be much appreciated. Many thanks!

To understand the difference between "do the operation in-place" and "return a new array", imagine a simpler problem:

You are given a list. Add 1 to every element of the list.

# returning a new array
def add_one_copy(l):
  return [x + 1 for x in l]

# in-place
def add_one_inplace(l):
  for i in range(len(l)):
    l[i] = l[i] + 1

Testing those two functions in the python interactive interpreter highlights the difference:

>>> a = [1, 2, 3]
>>> add_one_copy(a)
[2, 3, 4]
>>> a
[1, 2, 3]
>>> add_one_inplace(a)
>>> a
[2, 3, 4]

add_one_copy returns a result, but does not modify a . add_one_inplace does not return a result, but modifies the list. There is the same difference between the python functions sorted and list.sort :

>>> a = [3,4,2,1]
>>> sorted(a)
[1, 2, 3, 4]
>>> a
[3, 4, 2, 1]
>>> a.sort()
>>> a
[1, 2, 3, 4]

sorted returns a result, but does not modify the list. .sort modifies the list and does not return a result.

Now, the problem you are trying to solve is a little bit more complicated than just adding 1 to every element. The difficulty when solving your rotation problem in-place is that you are moving elements around in the matrix; when doing that, you must be careful not to overwrite the values of elements which you still need. Imagine a slightly harder problem:

You are given a list. Reverse the order of the elements in the list.

# returning a copy
def reverse_copy(l):
  return [l[len(l) - i - 1] for i in range(len(l))]

# in-place attempt, fall head-first in the trap, this is not working
def reverse_inplace_wrong(l):
  for i in range(len(l)):
    l[i] = l[len(l) - i - 1]

# in-place, correct
def reverse_inplace(l):
  for i in range(len(l)//2):
    tmp = l[len(l) - i - 1]
    l[len(l) - i - 1] = l[i]
    l[i] = tmp

Testing:

>>> a = [1,2,3,4,5,6,7]
>>> reverse_copy(a)
[7, 6, 5, 4, 3, 2, 1]
>>> a
[1, 2, 3, 4, 5, 6, 7]
>>> reverse_inplace_wrong(a)
>>> a
[7, 6, 5, 4, 5, 6, 7]
>>> a = [1,2,3,4,5,6,7]
>>> reverse_inplace(a)
>>> a
[7, 6, 5, 4, 3, 2, 1]

When reversing the list, I figured out that element at position i should go to position len(l) - i - 1 . When rotating the matrix, you have to figure out where the element at position (i,j) should go. And you have to be careful not to repeat the mistake I made in reverse_inplace_wrong .

For solving this problem we can also use Python built-in reverse() , wouldn't be a deal breaker:

class Solution:
    def rotate(self, A):
        A.reverse()
        for row in range(len(A)):
            for col in range(row):
                A[row][col], A[col][row] = A[col][row], A[row][col]

If you know C++ you may have a look at my solution.

I solved it using the logic of transpose of a matrix. And after transposing, I swapped the first column value with the last column, in the same row. Then the second column with the second last column, and so on.

void swapValues(int &valueOne, int &valueTwo) {
    int tempValue = valueOne;
    valueOne = valueTwo;
    valueTwo = tempValue;
}
    
void rotate(vector<vector<int> >& matrix) {
    int n = matrix.size();
    int halfN = n / 2;

    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
            if(i != j && j > i) {
                swapValues(matrix[i][j], matrix[j][i]);
            }
        }

        for (int j=0; j<halfN; j++) {
            swapValues(matrix[i][j], matrix[i][n-1-j]);
        }
    }
}
class Solution:
    def rotate(self, matrix):
        rotate_mat = []
        for l in range(len(matrix)):
            mat = [i[l] for i in matrix][::-1]
            rotate_mat.append(mat)
        return rotate_mat

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM