-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathset-matrix-zeroes.cpp
142 lines (122 loc) · 4.12 KB
/
set-matrix-zeroes.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Copyright (c) 2018 Christopher Friedt
*
* SPDX-License-Identifier: MIT
*/
#include <cstring>
#include <strings.h>
#include <unordered_set>
#include <vector>
using namespace std;
class Solution {
public:
// https://leetcode.com/problems/set-matrix-zeroes/
void setZeroes(vector<vector<int>> &matrix) {
// This is O( M x N ) in time and O( 1 ) in space
size_t rows = matrix.size();
size_t cols = 0 == matrix.size() ? 0 : matrix[0].size();
if (0 == rows || 0 == cols) {
return;
}
bool row0 = false;
bool col0 = false;
for (size_t row = 0; row < rows; row++) {
for (size_t col = 0; col < cols; col++) {
if (0 == matrix[row][col]) {
if (0 == row && 0 == col) {
row0 = true;
col0 = true;
continue;
}
if (0 == row) {
row0 = true;
} else {
matrix[row][0] = 0;
}
if (0 == col) {
col0 = true;
} else {
matrix[0][col] = 0;
}
}
}
}
for (size_t row = 1; row < rows; row++) {
if (0 == matrix[row][0]) {
for (size_t col = 0; col < cols; col++) {
matrix[row][col] = 0;
}
}
}
for (size_t col = 0; col < cols; col++) {
if (0 == matrix[0][col]) {
for (size_t row = 0; row < rows; row++) {
matrix[row][col] = 0;
}
}
}
if (row0) {
for (size_t col = 0; col < cols; col++) {
matrix[0][col] = 0;
}
}
if (col0) {
for (size_t row = 0; row < rows; row++) {
matrix[row][0] = 0;
}
}
}
/*
void setZeroes(vector<vector<int>>& matrix) {
if ( matrix.size() == 0 || matrix[ 0 ].size() == 0 ) {
return;
}
if ( matrix.size() > 64 || matrix[ 0 ].size() > 64 ) {
throw invalid_argument( "matrix dimensions too large"
);
}
// use bits to encode which rows / cols are to be zeroed
uint64_t zero_rows = 0;
uint64_t zero_cols = 0;
size_t rows = matrix.size();
size_t cols = matrix[ 0 ].size();
// O( rows * cols ) :(
for( size_t row = 0; row < rows; row++ ) {
for( size_t col = 0; col < cols; col++ ) {
if ( 0xffffffff == zero_rows || 0xffffffff ==
zero_cols ) { break;
}
if ( 0 == matrix[ row ][ col ] ) {
zero_rows |= (uint64_t(1) << row);
zero_cols |= (uint64_t(1) << col);
}
}
}
// if either all rows or all cols are to be zero'd, the entire
// matrix should be zero'd. std::fill (hopefully?) uses some
// simd intrinsics and can do this very quickly and
efficiently
// so it should be a shortcut.
if ( 0xffffffff == zero_rows || 0xffffffff == zero_cols ) {
for( size_t row = 0; row < rows; row++ ) {
fill( matrix[ row ].begin(), matrix[ row
].end(), 0 );
}
return;
}
// iterative approach for sparse zeros
for( size_t offs = 0, fsb = ::ffsll( zero_rows ); fsb > 0;
zero_rows >>= fsb, offs += fsb, fsb = ::ffsll( zero_rows ) ) { size_t row =
offs + fsb - 1; for( size_t col = 0; col < cols; col++ ) { matrix[ row ][
col ] = 0;
}
}
for( size_t offs = 0, fsb = ::ffsll( zero_cols ); fsb > 0;
zero_cols >>= fsb, offs += fsb, fsb = ::ffsll( zero_cols ) ) { size_t col =
offs + fsb - 1; for( size_t row = 0; row < rows; row++ ) { matrix[ row ][
col ] = 0;
}
}
}
*/
};