题目描述
给你一个大小为 m x n
的二维字符数组 picture
,表示一张黑白图像,数组中的 'B'
表示黑色像素,'W'
表示白色像素。另给你一个整数 target
,请你找出并返回符合规则的 黑色 孤独像素的数量。
黑色孤独像素是指位于某一特定位置 (r, c)
的字符 'B'
,其中:
- 行
r
和列 c
中的黑色像素恰好有 target
个。
- 列
c
中所有黑色像素所在的行必须和行 r
完全相同。
示例 1:
输入:picture = [["W","B","W","B","B","W"],["W","B","W","B","B","W"],["W","B","W","B","B","W"],["W","W","B","W","B","W"]], target = 3
输出:6
解释:所有绿色的 'B' 都是我们所求的像素(第 1 列和第 3 列的所有 'B' )
以行 r = 0 和列 c = 1 的 'B' 为例:
- 规则 1 ,行 r = 0 和列 c = 1 都恰好有 target = 3 个黑色像素
- 规则 2 ,列 c = 1 的黑色像素分别位于行 0,行 1 和行 2。和行 r = 0 完全相同。
示例 2:
输入:picture = [["W","W","B"],["W","W","B"],["W","W","B"]], target = 1
输出:0
提示:
m == picture.length
n == picture[i].length
1 <= m, n <= 200
picture[i][j]
为 'W'
或 'B'
1 <= target <= min(m, n)
解法
方法一:计数
题目中条件二相当于要求对于每一列中所有包含黑色像素的行,这些行完全相同。
因此,我们可以用一个邻接表 $g$ 来存储每一列中所有包含黑色像素的行,即 $g[j]$ 表示第 $j$ 列中所有包含黑色像素的行的集合。另外,用一个数组 $rows$ 来存储每一行中黑色像素的数量。
接下来,我们遍历每一列,对于每一列,我们找到第一个包含黑色像素的行 $i_1$,如果这一行中黑色像素的数量不等于 $target$,那么这一列不可能包含孤独像素,直接跳过。否则,我们检查这一列中所有包含黑色像素的行是否和第 $i_1$ 行完全相同,如果是,则这一列中所有的黑色像素都是孤独像素,答案加上 $target$。
遍历结束后,返回答案即可。
时间复杂度 $O(m \times n^2)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | class Solution:
def findBlackPixel(self, picture: List[List[str]], target: int) -> int:
rows = [0] * len(picture)
g = defaultdict(list)
for i, row in enumerate(picture):
for j, x in enumerate(row):
if x == "B":
rows[i] += 1
g[j].append(i)
ans = 0
for j in g:
i1 = g[j][0]
if rows[i1] != target:
continue
if len(g[j]) == rows[i1] and all(picture[i2] == picture[i1] for i2 in g[j]):
ans += target
return ans
|
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 | class Solution {
public int findBlackPixel(char[][] picture, int target) {
int m = picture.length;
int n = picture[0].length;
List<Integer>[] g = new List[n];
Arrays.setAll(g, k -> new ArrayList<>());
int[] rows = new int[m];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (picture[i][j] == 'B') {
++rows[i];
g[j].add(i);
}
}
}
int ans = 0;
for (int j = 0; j < n; ++j) {
if (g[j].isEmpty() || (rows[g[j].get(0)] != target)) {
continue;
}
int i1 = g[j].get(0);
int ok = 0;
if (g[j].size() == rows[i1]) {
ok = target;
for (int i2 : g[j]) {
if (!Arrays.equals(picture[i1], picture[i2])) {
ok = 0;
break;
}
}
}
ans += ok;
}
return ans;
}
}
|
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 | class Solution {
public:
int findBlackPixel(vector<vector<char>>& picture, int target) {
int m = picture.size();
int n = picture[0].size();
vector<int> g[n];
vector<int> rows(m);
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (picture[i][j] == 'B') {
++rows[i];
g[j].push_back(i);
}
}
}
int ans = 0;
for (int j = 0; j < n; ++j) {
if (g[j].empty() || (rows[g[j][0]] != target)) {
continue;
}
int i1 = g[j][0];
int ok = 0;
if (g[j].size() == rows[i1]) {
ok = target;
for (int i2 : g[j]) {
if (picture[i1] != picture[i2]) {
ok = 0;
break;
}
}
}
ans += ok;
}
return ans;
}
};
|
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 | func findBlackPixel(picture [][]byte, target int) (ans int) {
m := len(picture)
n := len(picture[0])
g := make([][]int, n)
rows := make([]int, m)
for i, row := range picture {
for j, x := range row {
if x == 'B' {
rows[i]++
g[j] = append(g[j], i)
}
}
}
for j := 0; j < n; j++ {
if len(g[j]) == 0 || rows[g[j][0]] != target {
continue
}
i1 := g[j][0]
ok := 0
if len(g[j]) == rows[i1] {
ok = target
for _, i2 := range g[j] {
if !bytes.Equal(picture[i1], picture[i2]) {
ok = 0
break
}
}
}
ans += ok
}
return
}
|
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 | function findBlackPixel(picture: string[][], target: number): number {
const m: number = picture.length;
const n: number = picture[0].length;
const g: number[][] = Array.from({ length: n }, () => []);
const rows: number[] = Array(m).fill(0);
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (picture[i][j] === 'B') {
++rows[i];
g[j].push(i);
}
}
}
let ans: number = 0;
for (let j = 0; j < n; ++j) {
if (g[j].length === 0 || rows[g[j][0]] !== target) {
continue;
}
const i1: number = g[j][0];
let ok: number = 0;
if (g[j].length === rows[i1]) {
ok = target;
for (const i2 of g[j]) {
if (picture[i1].join('') !== picture[i2].join('')) {
ok = 0;
break;
}
}
}
ans += ok;
}
return ans;
}
|