程序员老鬼

有位同事被解雇了。他立刻退出了工作群,删除了同事和领导的联系。到了中午,组长试图联系他,但发现自己也被删除了~

早上刚被裁,中午全组集体“查无此人”,这哥们下手是真利索。

人一出门,工作群秒退,领导同事一键清空,连组长中午想捞他说两句,才发现自己也早被删干净了。还让别人帮忙联系,结果一圈问下来,大家整整齐齐,全躺在黑名单外面。那画面感,真有点好笑,HR看完估计都得愣一下。

Image

有网友说这才叫职业切割,既然公司先翻脸,那我也没义务陪你演温情戏。也有人觉得太绝,把后路都堵死了。可我看这事,重点还真不在删不删,而是这人八成早就想明白了:都到解雇这一步了,留着联系方式干吗,等着以后深夜接一句“方便交接一下吗”?

成年人的体面,有时候不是握手告别,是连头像都不给你留。

面试题:角矩形的数量

这个题我第一眼就不太信暴力。

给你一个只包含 0 和 1 的矩阵,问能组成多少个角矩形。所谓角矩形,不是让你把整个矩形内部都填满,只要求四个角都是 1。很多人上来就想枚举左上、右上、左下、右下四个点,这种写法能过小数据,一上规模基本就开始喘。写算法题,最怕这种“看着直观,跑起来冒烟”的路子。写法气质参考你给的几篇技术文风格来压了压 AI 味:

这题真正该盯的,不是四个点,而是两行之间有多少列同时为 1。

你想一下,假设第 i 行和第 j 行,在第 2 列、第 5 列、第 9 列上都同时为 1,那这两行就能拿这 3 列里的任意 2 列,拼出一个角矩形。数量就是组合数:

count = k * (k - 1) / 2;

这里 k 表示两行同列为 1 的个数。

所以这题顺序应该是这样排:

先枚举行对。 再数这两行有多少个公共的 1 列。 最后把 k 转成矩形个数加起来。

代码不用整得太花,现场能看懂最重要:

publicclassSolution{
publicintcountCornerRectangles(int[][] grid){
int rows = grid.length;
int cols = grid[0].length;
int ans = 0;

for (int r1 = 0; r1 < rows; r1++) {
for (int r2 = r1 + 1; r2 < rows; r2++) {
int same = 0;
for (int c = 0; c < cols; c++) {
if (grid[r1][c] == 1 && grid[r2][c] == 1) {
                        same++;
                    }
                }
if (same >= 2) {
                    ans += same * (same - 1) / 2;
                }
            }
        }
return ans;
    }
}

这段代码没什么玄学,时间复杂度是 O(row^2 * col)。如果矩阵是行数不大、列数中等,这个解法已经很稳了。

举个小例子:

int[][] grid = {
    {1, 0, 0, 1, 0},
    {0, 0, 1, 0, 1},
    {0, 0, 0, 1, 0},
    {1, 0, 1, 0, 1}
};

看第 0 行和第 3 行,它们在第 0 列都为 1,但只有这一列重合,不够组成矩形。 看第 1 行和第 3 行,它们在第 2 列、第 4 列都为 1,正好能组成 1 个角矩形。

这题还有个容易写别扭的地方:有人喜欢先收集每一行所有值为 1 的列,再做交集。能写,但没必要,代码会变碎,常数也不见得好看。算法题里这种二维布尔判断,能一层层扫过去,就别引入多余结构。

再说一句经验话:这题本质上不是“找矩形”,而是“找两行的公共列对数”。一旦视角转过来,题目就顺了。很多中等题卡人的地方,不在代码,而在你盯错了对象。盯四个角,越写越乱;盯两行公共 1,三层循环就收工。就这么回事。