[Leetcode] [Tutorial] Matrix


73. Matrix zeroing

Given an mxn matrix, if an element is 0, set all elements in its row and column to 0. Please use the in-place algorithm.

Example:
Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output: [[0,0,0,0], [0,4,5,0],[0,3,1,0]]

Solution

To solve this problem, we can use the first row and column of the matrix to record whether other rows and columns should be set to 0. But before that, we need two flag variables to record whether the first row and the first column themselves should be set to 0.

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        m = len(matrix)
        n = len(matrix[0])

        first_row_has_zero = False
        first_col_has_zero = False

        # Check if first row and first column have zero
        for i in range(m):
            if matrix[i][0] == 0:
                first_col_has_zero = True
                break

        for j in range(n):
            if matrix[0][j] == 0:
                first_row_has_zero = True
                break

        # Use first row and first column as markers
        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][j] == 0:
                    matrix[i][0] = 0
                    matrix[0][j] = 0

        # Update the rest of the matrix
        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][0] == 0 or matrix[0][j] == 0:
                    matrix[i][j] = 0

        # Update first row and first column
        if first_row_has_zero:
            for j in range(n):
                matrix[0][j] = 0

        if first_col_has_zero:
            for i in range(m):
                matrix[i][0] = 0

54. Spiral matrix

Given a matrix matrix with m rows and n columns, please return all elements in the matrix in clockwise spiral order.

Example:
Input: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
Output: [1,2,3,4,8, 12,11,10,9,5,6,7]

Solution

class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        if not matrix:
            return []

        top, bottom = 0, len(matrix) - 1
        left, right = 0, len(matrix[0]) - 1
        order = []

        while top <= bottom and left <= right:
            for i in range(left, right + 1):
                order.append(matrix[top][i])
            top += 1
            
            for i in range(top, bottom + 1):
                order.append(matrix[i][right])
            right -= 1
            
            if top <= bottom:
                for i in range(right, left - 1, -1):
                    order.append(matrix[bottom][i])
                bottom -= 1
            
            if left <= right:
                for i in range(bottom, top - 1, -1):
                    order.append(matrix[i][left])
                left += 1

        return order

For traversing the upper boundary from left to right and traversing the right boundary from top to bottom, since we update top and right every time, we can guarantee that there will be no repeated traversal. This means that you can perform both traversals unconditionally.

For traversing the lower border from right to left and traversing the left border from bottom to top, since top and right have been updated before traversal, we need to check whether top <= bottom and left <= right to determine whether there is anything left. The rows or columns need to be traversed. If top > bottom or left > right, it means that the row or column has been traversed in the previous traversal, so it cannot be traversed again.

48. Rotate images

Given an n × n two-dimensional matrix matrix representing an image. Please rotate the image 90 degrees clockwise.

Example:
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2], [9,6,3]]

Solution

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        n = len(matrix)
        # 对角线翻转
        for i in range(n):
            for j in range(i, n):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
        # x轴翻转
        for i in range(n):
            matrix[i] = matrix[i][::-1]

or

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        n = len(matrix)

        for i in range(0, n):
            for j in range(0, n - i):
                matrix[i][j], matrix[n - 1 - j][n - 1 - i] = matrix[n - 1 - j][n - 1 - i], matrix[i][j]

        for j in range(0, n):
            for i in range(0, (n - 1) // 2 + 1):
                matrix[i][j], matrix[n - 1 - i][j] = matrix[n - 1 - i][j], matrix[i][j]

Another way to solve the problem of rotating the image 90 degrees clockwise is a four-element ring replacement.

  • Define two level loops. The outer loop i represents the current processing level, starting from the outermost layer and going to the center of the matrix; the inner loop j represents the starting point of loop replacement in the current level and ends at the end of the current level.
  • In each layer, a four-element loop replacement is performed, that is, the element in the upper left corner is moved to the upper right corner, the element in the upper right corner is moved to the lower right corner, the element in the lower right corner is moved to the lower left corner, and the element in the lower left corner is moved to the upper left corner.
class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        n = len(matrix)
        for i in range(n // 2):
            for j in range((n + 1) // 2):
                matrix[i][j], matrix[n - j - 1][i], matrix[n - i - 1][n - j - 1], matrix[j][n - i - 1] = matrix[n - j - 1][i], matrix[n - i - 1][n - j - 1], matrix[j][n - i - 1], matrix[i][j]

240. Searching a two-dimensional matrix II

Write an efficient algorithm to search for a target value target in an mxn matrix. The elements of each row of this matrix are arranged in ascending order from left to right, and the elements of each column are arranged in ascending order from top to bottom.

Example:
Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14, 17,24],[18,21,23,26,30]], target = 5
output: true

Solution

Just with each row ascending from left to right and each column ascending from top to bottom, we cannot treat the entire matrix as a sorted list and do a regular binary search because the elements across the rows are not necessarily ordered.

However, we can use a binary search for each line to determine whether the target is in the line, and thus determine whether the target appears.

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        for row in matrix:
            idx = bisect.bisect_left(row, target)
            if idx < len(row) and row[idx] == target:
                return True
        return False

bisect is a built-in module that provides binary search functionality for ordered lists. The bisect module includes the following main functions:

bisect_left(list, num, beg, end): This function is used to find the insertion point of the number num in the ordered list to maintain the order of the list. If num already exists in the list, the insertion point is before (ie to the left of) the existing element. The beg and end parameters default to 0 and len(list), but can be set to a specified range.

If we look at the elements in the upper right or lower left corner of the matrix, we find an interesting pattern. Starting from the upper right corner:

  • If the target value is smaller than this element, then we can exclude this column, because all the elements of this column are larger than the element in the upper right corner (because they are in ascending order), so they are definitely larger than the target value.
  • If the target value is larger than this element, then we can exclude this row, because all elements of this row are smaller than the upper right element (because they are in ascending order), so they are definitely smaller than the target value.
  • If the target value is equal to this element, then we have found the target value.

A similar pattern is seen from the lower left corner. In this way, we can decide whether to exclude rows or columns based on the comparison of the target value and the current element.

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        m, n = len(matrix), len(matrix[0])
        i, j = 0, n - 1
        while i < m and j >= 0:
            if matrix[i][j] == target:
                return True
            elif matrix[i][j] < target:
                i += 1
            else:
                j -= 1
        return False

Guess you like

Origin blog.csdn.net/weixin_45427144/article/details/131424930