73. 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?

Hint:

  1. If any cell of the matrix has a zero we can record its row and column number using additional memory. But if you don’t want to use extra memory then you can manipulate the array instead. i.e. simulating exactly what the question says.
  2. Setting cell values to zero on the fly while iterating might lead to discrepancies. What if you use some other integer value as your marker? There is still a better approach for this problem with 0(1) space.
  3. We could have used 2 sets to keep a record of rows/columns which need to be set to zero. But for an O(1) space solution, you can use one of the rows and and one of the columns to keep track of this information.
  4. We can use the first cell of every row and column as a flag. This flag would determine whether a row or column has been set to zero.

方法0:

思路:

根据follow up里面列出的提示,如果用O(m + n)的方法,就是记录一个row,col vector,每一个标记是否有0 出现过,最后遍历一次把出现过0的地方都换成0。

Complexity

Time Complexity: O(M×N) where M and N are the number of rows and columns respectively.
Space Complexity: O(M + N).

方法1:

官方题解: https://leetcode.com/problems/set-matrix-zeroes/solution/
grandyang: http://www.cnblogs.com/grandyang/p/4341590.html

思路:

但是如何用O(1)的方法呢?一开始的想法是遍历一遍,将每个非0位置改为1,一共遍历2次,计算每一行的累计和。如果小于m(列)或n(行),变为0。借用了tic-tac-toc的办法, 但是这个方法时间上不是很有效,需要遍历3遍。solution的解给出的更加简单。solution的第一种O(1)解法是遇见每一个0,将该行该列改为一个特殊数字,比如-100000。最后遍历一遍将所有特殊符号设为0。

  • 先扫描第一行第一列,如果有0,则将各自的flag设置为true
  • 然后扫描除去第一行第一列的整个数组,如果有0,则将对应的第一行和第一列的数字赋0
  • 再次遍历除去第一行第一列的整个数组,如果对应的第一行和第一列的数字有一个为0,则将当前值赋0
  • 最后根据第一行第一列的flag来更新第一行第一列

这里暂时用两个flag来标记第一行和第一列而不直接更新为0是因为,如果第一行第一列在一开始就被都set成0,那么之后遍历的时候,将查找不到之前存储的是否含有0的信息,会将所有数字都设为0.

易错点

  1. 中间两步不能包含第一行第一列

Complexity

Time complexity
Space complexity

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        bool zeroRow = false, zeroCol = false;
        // 
        for (int i = 0; i < matrix.size(); i++){
            if (matrix[i][0] == 0) zeroCol = true;
        }
        
        for (int j = 0; j < matrix[0].size(); j++){
            if (matrix[0][j] == 0) zeroRow = true;
        }
        
        for (int i = 1; i < matrix.size(); i++){
            for (int j = 1 ; j < matrix[0].size(); j++){
                if (matrix[i][j] == 0) matrix[i][0] = matrix[0][j] = 0;
            }
        }
        
        for (int i = 1; i < matrix.size(); i++){
            for (int j = 1 ; j < matrix[0].size(); j++){
                if (matrix[0][j] == 0 || matrix[i][0] == 0) 
                    matrix[i][j] = 0;
            }
        }
        
        if (zeroCol){
            for (int i = 0; i < matrix.size(); i++) matrix[i][0] = 0;
        }
        if (zeroRow){
            for (int j = 0; j < matrix[0].size(); j++) matrix[0][j] = 0;
        }
        return;
    }
};
import numpy as np import pandas as pd import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ["SimHei"] # 单使用会使负号显示错误 plt.rcParams['axes.unicode_minus'] = False # 把负号正常显示 # 读取北京房价数据 path = 'data.txt' data = pd.read_csv(path, header=None, names=['房子面积', '房子价格']) print(data.head(10)) print(data.describe()) # 绘制散点图 data.plot(kind='scatter', x='房子面积', y='房子价格') plt.show() def computeCost(X, y, theta): inner = np.power(((X * theta.T) - y), 2) return np.sum(inner) / (2 * len(X)) data.insert(0, 'Ones', 1) cols = data.shape[1] X = data.iloc[:,0:cols-1]#X是所有行,去掉最后一列 y = data.iloc[:,cols-1:cols]#X是所有行,最后一列 print(X.head()) print(y.head()) X = np.matrix(X.values) y = np.matrix(y.values) theta = np.matrix(np.array([0,0])) print(theta) print(X.shape, theta.shape, y.shape) def gradientDescent(X, y, theta, alpha, iters): temp = np.matrix(np.zeros(theta.shape)) parameters = int(theta.ravel().shape[1]) cost = np.zeros(iters) for i in range(iters): error = (X * theta.T) - y for j in range(parameters): term = np.multiply(error, X[:, j]) temp[0, j] = theta[0, j] - ((alpha / len(X)) * np.sum(term)) theta = temp cost[i] = computeCost(X, y, theta) return theta, cost alpha = 0.01 iters = 1000 g, cost = gradientDescent(X, y, theta, alpha, iters) print(g) print(computeCost(X, y, g)) x = np.linspace(data.Population.min(), data.Population.max(), 100) f = g[0, 0] + (g[0, 1] * x) fig, ax = plt.subplots(figsize=(12,8)) ax.plot(x, f, 'r', label='Prediction') ax.scatter(data.Population, data.Profit, label='Traning Data') ax.legend(loc=2) ax.set_xlabel('房子面积') ax.set_ylabel('房子价格') ax.set_title('北京房价拟合曲线图') plt.show()
最新发布
06-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值