社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
上周阿里面试的题目,要求现场50分钟手写。原题文字很长,理解完,意思如下:
一个0,1矩阵,行列不定。相连的1为同一区域,区域中1的个数越多,区域越大。
求最大区域1的个数。(相连可以是上下左右相邻,也可以是斜向相邻)
示例1:
总共三个区域,最大区域1的个数为3
示例2:
总共一个区域,最大区域1的个数为10
1,对矩阵做一次遍历,顺序遍历,将为1元素置为1,2,3…
2,对矩阵做二次遍历,顺序遍历,将相同区域的非0元素置为相同区域的非0最小值
3,对矩阵做三次遍历,逆序遍历,将相同区域的非0元素置为相同区域的非0最小值
4,矩阵做四次遍历,统计每个非0元素的元素个数,返回最大个数
以示例二为例,矩阵在前三次遍历后的状态如下:
class MatrixRegion {
/**
* 求0,1矩阵最大1区域元素个数 上下左右,斜上斜下为同一区域
*/
int region(int[][] matrix) {
/* 对矩阵做一次遍历,顺序遍历,将为1元素置为1,2,3... */
int tmp = 1;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == 1) {
matrix[i][j] = tmp;
tmp++;
}
}
}
/* 对矩阵做二次遍历,顺序遍历,将相同区域的非0元素置为相同区域的非0最小值 */
Map<Integer, Integer> map;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
settleMinValue(matrix, i, j);
}
}
/* 对矩阵做三次遍历,逆序遍历,将相同区域的非0元素置为相同区域的非0最小值 */
for (int i = matrix.length - 1; i >= 0; i--) {
for (int j = matrix[i].length - 1; j >= 0; j--) {
settleMinValue(matrix, i, j);
}
}
/* 矩阵做四次遍历,统计每个非0元素的元素个数,返回最大个数 */
map = new HashMap<>();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] != 0) {
if (map.get(matrix[i][j]) != null) {
map.put(matrix[i][j], map.get(matrix[i][j]) + 1);
} else {
map.put(matrix[i][j], 1);
}
}
}
}
int num = 0;
for (Integer key : map.keySet()) {
if (map.get(key) > num) {
num = map.get(key);
}
}
return num;
}
/**
* 获取矩阵指定多个元素的最小值
*/
int getMinValue(int[][] matrix, Map<Integer, Integer> map) {
int minValue = -1;
for (Integer key : map.keySet()) {
if (minValue == -1) {
minValue = matrix[key][map.get(key)];
continue;
}
if (matrix[key][map.get(key)] < minValue) {
minValue = matrix[key][map.get(key)];
}
}
return minValue;
}
/**
* 设置区域非0元素为区域非0最小值
*/
void settleMinValue(int[][] matrix, int i, int j) {
Map<Integer, Integer> map;
if (matrix[i][j] > 0) {
map = new HashMap<>();
map.put(i, j);
if (elementExist(matrix, i - 1, j)) map.put(i - 1, j);
if (elementExist(matrix, i + 1, j)) map.put(i + 1, j);
if (elementExist(matrix, i, j - 1)) map.put(i, j - 1);
if (elementExist(matrix, i, j + 1)) map.put(i, j + 1);
if (elementExist(matrix, i - 1, j - 1)) map.put(i - 1, j - 1);
if (elementExist(matrix, i - 1, j + 1)) map.put(i - 1, j + 1);
if (elementExist(matrix, i + 1, j + 1)) map.put(i + 1, j + 1);
if (elementExist(matrix, i + 1, j - 1)) map.put(i + 1, j - 1);
int minValue = getMinValue(matrix, map);
for (Integer key : map.keySet()) {
matrix[key][map.get(key)] = minValue;
}
}
}
/**
* 判断元素指定下标元素在矩阵是否且大于0存在
*/
boolean elementExist(int[][] matrix, int x, int y) {
if (x < 0 || y < 0) {
return false;
}
if (x >= matrix.length || y >= matrix[0].length) {
return false;
}
if (matrix[x][y] == 0) {
return false;
}
return true;
}
}
这道题的解答觉得方案不是很好,有点僵硬。希望大神们能提供更好的解决方案和思路。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!