Skip to content

Commit b98b6b3

Browse files
authored
Update strange-printer-ii.cpp
1 parent 70d82ab commit b98b6b3

File tree

1 file changed

+80
-19
lines changed

1 file changed

+80
-19
lines changed

C++/strange-printer-ii.cpp

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,79 @@
33
// Space: O(e)
44

55
class Solution {
6+
public:
7+
bool isPrintable(vector<vector<int>>& targetGrid) {
8+
unordered_map<int, vector<int>> boxes;
9+
for (int r = 0; r < size(targetGrid); ++r) {
10+
for (int c = 0; c < size(targetGrid[r]); ++c) {
11+
if (!boxes.count(targetGrid[r][c])) {
12+
boxes[targetGrid[r][c]] = {r, c, r, c};
13+
} else {
14+
boxes[targetGrid[r][c]][0] = min(boxes[targetGrid[r][c]][0], r);
15+
boxes[targetGrid[r][c]][1] = min(boxes[targetGrid[r][c]][1], c);
16+
boxes[targetGrid[r][c]][2] = max(boxes[targetGrid[r][c]][2], r);
17+
boxes[targetGrid[r][c]][3] = max(boxes[targetGrid[r][c]][3], c);
18+
}
19+
}
20+
}
21+
unordered_map<int, unordered_set<int>> adj;
22+
for (const auto& [color, box] : boxes) {
23+
for (int r = box[0]; r <= box[2]; ++r) {
24+
for (int c = box[1]; c <= box[3]; ++c) {
25+
if (targetGrid[r][c] != color) {
26+
adj[color].emplace(targetGrid[r][c]);
27+
}
28+
}
29+
}
30+
}
31+
unordered_map<int, int> lookup;
32+
for (const auto& [color, _] : boxes) {
33+
if (lookup.count(color)) {
34+
continue;
35+
}
36+
if (hasCycle(adj, color, &lookup)) {
37+
return false;
38+
}
39+
}
40+
return true;
41+
}
42+
43+
private:
44+
enum State {VISITING, VISITED};
45+
46+
bool hasCycle(const unordered_map<int, unordered_set<int>>& adj,
47+
int color,
48+
unordered_map<int, int> *lookup) {
49+
vector<pair<int, int>> stk = {{1, color}};
50+
while (!empty(stk)) {
51+
const auto [step, color] = stk.back(); stk.pop_back();
52+
if (step == 1) {
53+
(*lookup)[color] = VISITING;
54+
stk.emplace_back(2, color);
55+
if (!adj.count(color)) {
56+
continue;
57+
}
58+
for (const auto& new_color : adj.at(color)) {
59+
if (lookup->count(new_color)) {
60+
if ((*lookup)[new_color] == VISITED) {
61+
continue;
62+
}
63+
return true; // VISITING
64+
}
65+
stk.emplace_back(1, new_color);
66+
}
67+
} else {
68+
(*lookup)[color] = VISITED;
69+
}
70+
}
71+
return false;
72+
}
73+
};
74+
75+
// Time: O(c * m * n + e), c is the number of colors
76+
// , e is the number of edges in adj, at most O(c^2)
77+
// Space: O(e)
78+
class Solution2 {
679
public:
780
bool isPrintable(vector<vector<int>>& targetGrid) {
881
static const int MAX_COLOR = 60;
@@ -49,28 +122,16 @@ class Solution {
49122
bool hasCycle(const unordered_map<int, unordered_set<int>>& adj,
50123
int color,
51124
unordered_map<int, int> *lookup) {
52-
vector<pair<int, int>> stk = {{1, color}};
53-
while (!empty(stk)) {
54-
const auto [step, color] = stk.back(); stk.pop_back();
55-
if (step == 1) {
56-
(*lookup)[color] = VISITING;
57-
stk.emplace_back(2, color);
58-
if (!adj.count(color)) {
59-
continue;
125+
(*lookup)[color] = VISITING;
126+
if (adj.count(color)) {
127+
for (const auto& new_color : adj.at(color)) {
128+
if ((!lookup->count(new_color) && hasCycle(adj, new_color, lookup)) ||
129+
(*lookup)[new_color] == VISITING) {
130+
return true;
60131
}
61-
for (const auto& new_color : adj.at(color)) {
62-
if (lookup->count(new_color)) {
63-
if ((*lookup)[new_color] == VISITED) {
64-
continue;
65-
}
66-
return true; // VISITING
67-
}
68-
stk.emplace_back(1, new_color);
69-
}
70-
} else {
71-
(*lookup)[color] = VISITED;
72132
}
73133
}
134+
(*lookup)[color] = VISITED;
74135
return false;
75136
}
76137
};

0 commit comments

Comments
 (0)