Skip to content

Latest commit

 

History

History
268 lines (228 loc) · 7.88 KB

File metadata and controls

268 lines (228 loc) · 7.88 KB
comments difficulty edit_url tags
true
中等
数组
哈希表
矩阵

English Version

题目描述

给你一个大小为 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$ 分别是矩阵的行数和列数。

Python3

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

Java

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;
    }
}

C++

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;
    }
};

Go

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
}

TypeScript

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;
}