阿里远程面试—手写算法 - Go语言中文社区

阿里远程面试—手写算法


一、原题:

上周阿里面试的题目,要求现场50分钟手写。原题文字很长,理解完,意思如下:
一个0,1矩阵,行列不定。相连的1为同一区域,区域中1的个数越多,区域越大。
求最大区域1的个数。(相连可以是上下左右相邻,也可以是斜向相邻)
示例1:

在这里插入图片描述
总共三个区域,最大区域1的个数为3

示例2:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200402153419262.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4NDA0OTkw,size_16,color_FFFFFF,t_70***总共一个区域,最大区域1的个数为10***
总共一个区域,最大区域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;
    }
}

四、结尾:

这道题的解答觉得方案不是很好,有点僵硬。希望大神们能提供更好的解决方案和思路。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_38404990/article/details/105270629
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢