Given a picture consisting of black and white pixels, and a positive integer N, find the number of black pixels located at some specific row R and column C that align with all the following rules:
- Row R and column C both contain exactly N black pixels.
- For all rows that have a black pixel at column C, they should be exactly the same as row R
The picture is represented by a 2D char array consisting of 'B' and 'W', which means black and white pixels respectively.
Example:
Input:
[['W', 'B', 'W', 'B', 'B', 'W'],
['W', 'B', 'W', 'B', 'B', 'W'],
['W', 'B', 'W', 'B', 'B', 'W'],
['W', 'W', 'B', 'W', 'B', 'W']]
N = 3
Output: 6
Explanation: All the bold 'B' are the black pixels we need (all 'B's at column 1 and 3).
0 1 2 3 4 5 column index
0 [['W', 'B', 'W', 'B', 'B', 'W'],
1 ['W', 'B', 'W', 'B', 'B', 'W'],
2 ['W', 'B', 'W', 'B', 'B', 'W'],
3 ['W', 'W', 'B', 'W', 'B', 'W']]
row index
Take 'B' at row R = 0 and column C = 1 as an example:
Rule 1, row R = 0 and column C = 1 both have exactly N = 3 black pixels.
Rule 2, the rows have black pixel at column C = 1 are row 0, row 1 and row 2. They are exactly the same as row R = 0.
Note:
- The range of width and height of the input 2D array is [1,200].
這道題是之前那道Lonely Pixel I的拓展,我開始以為這次要考慮到對角線的情況,可是這次題目卻完全換了一種玩法。給了一個整數N,說對於均含有N個個黑像素的某行某列,如果該列中所有的黑像素所在的行都相同的話,該列的所有黑像素均為孤獨的像素,讓我們統計所有的這樣的孤獨的像素的個數。那么跟之前那題類似,我們還是要統計每一行每一列的黑像素的個數,而且由於條件二中要比較各行之間是否相等,如果一個字符一個字符的比較寫起來比較麻煩,我們可以用個trick,把每行的字符連起來,形成一個字符串,然后直接比較兩個字符串是否相等會簡單很多。然后我們遍歷每一行和每一列,如果某行和某列的黑像素剛好均為N,我們遍歷該列的所有黑像素,如果其所在行均相等,則說明該列的所有黑像素均為孤獨的像素,將個數加入結果res中,然后將該行的黑像素統計個數清零,以免重復運算,這樣我們就可以求出所有的孤獨的像素了,參見代碼如下:
解法一:
class Solution { public: int findBlackPixel(vector<vector<char>>& picture, int N) { if (picture.empty() || picture[0].empty()) return 0; int m = picture.size(), n = picture[0].size(), res = 0, k = 0; vector<int> rowCnt(m, 0), colCnt(n, 0); vector<string> rows(m, ""); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { rows[i].push_back(picture[i][j]); if (picture[i][j] == 'B') { ++rowCnt[i]; ++colCnt[j]; } } } for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (rowCnt[i] == N && colCnt[j] == N) { for (k = 0; k < m; ++k) { if (picture[k][j] == 'B') { if (rows[i] != rows[k]) break; } } if (k == m) { res += colCnt[j]; colCnt[j] = 0; } } } } return res; } };
看到論壇中的比較流行的解法是用哈希表來做的,建立黑像素出現個數為N的行和其出現次數之間的映射,然后我們就只需要統計每列的黑像素的個數,然后我們遍歷哈希表,找到出現次數剛好為N的行,說明矩陣中有N個相同的該行,而且該行中的黑像素的個數也剛好為N個,那么第二個條件就已經滿足了,我們只要再滿足第一個條件就行了,我們在找黑像素為N個的列就行了,有幾列就加幾個N即可,參見代碼如下:
解法二:
class Solution { public: int findBlackPixel(vector<vector<char>>& picture, int N) { if (picture.empty() || picture[0].empty()) return 0; int m = picture.size(), n = picture[0].size(), res = 0; vector<int> colCnt(n, 0); unordered_map<string, int> u; for (int i = 0; i < m; ++i) { int cnt = 0; for (int j = 0; j < n; ++j) { if (picture[i][j] == 'B') { ++colCnt[j]; ++cnt; } } if (cnt == N) ++u[string(picture[i].begin(), picture[i].end())]; } for (auto a : u) { if (a.second != N) continue; for (int i = 0; i < n; ++i) { res += (a.first[i] == 'B' && colCnt[i] == N) ? N : 0; } } return res; } };
類似題目:
參考資料:
https://discuss.leetcode.com/topic/81686/verbose-java-o-m-n-solution-hashmap/2
https://discuss.leetcode.com/topic/87164/a-c-solution-based-on-the-top-rated-issue
