LeetCode[in-place]----Set Matrix Zeroes

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.

Example 1:

Input: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
Output: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

Example 2:

Input: 
[
  [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]
]

Follow up:

  • A straight forward solution using O(mn) space is probably a bad idea.
  • A simple improvement uses O(m + n) space, but still not the best solution.
  • Could you devise a constant space solution?

分析:

将一个m*n的矩阵中0元素所在的行和列均置为0,用原地算法。用原地算法意味着不能借助与m、n相关的数组空间。看到题后能直接想到一个非原地算法,即记录应该置0的行及列,遍历完成后再将这些行和列置零,但是需要最多m+n个空间。

但是如何用原地的方法呢?用原地的方法意味着我们不能借助额外的空间去记录哪一行哪一列应该置为0,我开始考虑位移运算、考虑是否可以移动(swap)矩阵元素、考虑是否能递归在递归结束后开始置零操作,但是都失败了。后来想到这种行和列的置零操作就类似于一个矩形的多米乐骨牌,又由倒下的多米乐骨牌与站立的骨牌样式不一样想到,我可以将应该置零的行或列先做个标记,每遇到一个应该置0的行,我将该行中每个非0的元素均置为特殊字符x,在遍历结束后,将矩阵所有的x都设置为0,这样即解决了所有0元素所在行和列均置0的操作。

实践中可以将特殊字符x设置为矩阵所有元素不包含的元素,如x为矩阵中最大的元素 + 1,而在Python中,我可以将x设置为字符。

代码:

    def setZeroes(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        row_num, col_num = len(matrix), len(matrix[0])
        for r in range(row_num):
            for c in range(col_num):
                if matrix[r][c] == 0:
                    self.setRowFlags(matrix, col_num, r)
                    self.setColFlags(matrix, row_num, c)

        for r in range(row_num):
            for c in range(col_num):
                if matrix[r][c] == 'f':
                    matrix[r][c] = 0

    def setRowFlags(self, matrix, col_num, row):
        for i in range(col_num):
            if matrix[row][i] != 0:
                matrix[row][i] = 'f'

    def setColFlags(self, matrix, row_num, col):
        for i in range(row_num):
            if matrix[i][col] != 0:
                matrix[i][col] = 'f'

晚上更新:

提交后看到了一种更好的解题思路:遍历矩阵元素,如果元素为0,则将矩阵的第一行和第一列的对应位置元素设为0,作为之后置零的标记,再通过一个额外的变量记录第一行和第一列是否要置零。

代码如下:

    def setZeroes(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        row_num, col_num = len(matrix), len(matrix[0])
        update_first_row, update_first_col = False, False
        for r in range(row_num):
            for c in range(col_num):
                if matrix[r][c] == 0:
                    matrix[r][0] = 0
                    matrix[0][c] = 0
                    if r == 0:
                        update_first_row = True
                    if c == 0:
                        update_first_col = True

        for r in range(1, row_num):  # update start from second row
            if matrix[r][0] == 0:
                for i in range(col_num):
                    matrix[r][i] = 0

        for c in range(1, col_num):  # update start from second column
            if matrix[0][c] == 0:
                for i in range(row_num):
                    matrix[i][c] = 0

        if update_first_row:
            for i in range(col_num):
                matrix[0][i] = 0

        if update_first_col:
            for i in range(row_num):
                matrix[i][0] = 0

猜你喜欢

转载自blog.csdn.net/whiterbear/article/details/84337729
今日推荐