“一代传奇”宗庆后谢幕,500亿元饮料帝国迎交棒时刻

宗庆后同志逝世

2月25日,娃哈哈集团发布讣告,娃哈哈创始人、董事长宗庆后同志,因病医治无效,于 2024-02-25 10:30 逝世,享年 79 岁。

这是一位伟大的企业家。

伟大的地方不仅仅在于,宗庆后 42 岁开始白手起家,50 多岁便三度(2010、2012 和 2013)登顶中国首富。

更难能可贵的是,宗庆后创业成功后仍简朴低调,从不轻易裁员,分红也是极其慷慨。

甚至在中国房地产高速发展的几十年里,在众多企业家纷纷投身房地产的大背景下,宗庆后唯一做过与房地产相关的事,就是在杭州核心地段给员工盖廉住房,方便大家上下班。

每每谈起自己的成功时,宗庆后说得最多的话是:

我自己是一个普通人,从底层崛起的凡人,幸运的是,我生于这一个大时代。

如此朴实的一位企业家,自然有着不俗的口碑。

讣告当天,雷军等人纷纷发文悼念:

中国需要更多像宗庆后这样的企业家。

英雄来了又去,传奇永不落幕。

...

回归主线。

简单做一道算法题,来源于「小米」真题库。

题目描述

平台:LeetCode

题号:764

在一个 <math xmlns="http://www.w3.org/1998/Math/MathML"> n × n n \times n </math>n×n 的矩阵 grid 中,除了在数组 mines 中给出的元素为 0,其他每个元素都为 1

<math xmlns="http://www.w3.org/1998/Math/MathML"> m i n e s [ i ] = [ x i , y i ] mines[i] = [x_i, y_i] </math>mines[i]=[xi,yi] 表示 <math xmlns="http://www.w3.org/1998/Math/MathML"> g r i d [ x i ] [ y i ] = 0 grid[x_i][y_i] = 0 </math>grid[xi][yi]=0。

返回 grid 中包含 1 的最大的轴对齐加号标志的阶数 。

如果未找到加号标志,则返回 0

一个 k 阶由 1 组成的 "轴对称"加号标志 具有中心网格 <math xmlns="http://www.w3.org/1998/Math/MathML"> g r i d [ r ] [ c ] = 1 grid[r][c] = 1 </math>grid[r][c]=1 ,以及 4 个从中心向上、向下、向左、向右延伸,长度为 k-1,由 1 组成的臂。

注意,只有加号标志的所有网格要求为 1 ,别的网格可能为 0 也可能为 1

示例 1:

lua 复制代码
输入: n = 5, mines = [[4, 2]]

输出: 2

解释: 在上面的网格中,最大加号标志的阶只能是2。一个标志已在图中标出。

示例 2:

lua 复制代码
输入: n = 1, mines = [[0, 0]]

输出: 0

解释: 没有加号标志,返回 0 。

提示:

  • <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 < = n < = 500 1 <= n <= 500 </math>1<=n<=500
  • <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 < = m i n e s . l e n g t h < = 5000 1 <= mines.length <= 5000 </math>1<=mines.length<=5000
  • <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 < = x i , y i < n 0 <= x_i, y_i < n </math>0<=xi,yi <n
  • 每一对 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( x i , y i ) (x_i, y_i) </math>(xi,yi) 都 不重复

预处理 + 模拟

假设点 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( x , y ) (x, y) </math>(x,y) 能够取得最大长度 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k,我们知道 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k 取决于以点 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( x , y ) (x, y) </math>(x,y) 为起点,四联通方向中「最短的连续 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 1 </math>1 的长度」。

基于此,我们可以建立四个大小为 <math xmlns="http://www.w3.org/1998/Math/MathML"> n × n n \times n </math>n×n 的矩阵(二维数组)abcd 分别代表四个方向连续 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 1 </math>1 的前缀数:

数据范围为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 500 500 </math>500,预处理前缀数组复杂度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n 2 ) O(n^2) </math>O(n2),统计答案复杂度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n 2 ) O(n^2) </math>O(n2),时间复杂度没有问题。

再考虑空间,建立四个方向的前缀数组所需空间为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 500 × 500 × 4 = 1 0 6 500 \times 500 \times 4 = 10^6 </math>500×500×4=106,即使加上原矩阵 g 也不会有 MLE 风险,空间复杂度也没有问题。

Java 代码:

Java 复制代码
class Solution {
    public int orderOfLargestPlusSign(int n, int[][] mines) {
        int[][] g = new int[n + 10][n + 10];
        for (int i = 1; i <= n; i++) Arrays.fill(g[i], 1);
        for (int[] info : mines) g[info[0] + 1][info[1] + 1] = 0;
        int[][] a = new int[n + 10][n + 10], b = new int[n + 10][n + 10], c = new int[n + 10][n + 10], d = new int[n + 10][n + 10];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (g[i][j] == 1) {
                    a[i][j] = a[i - 1][j] + 1;
                    b[i][j] = b[i][j - 1] + 1;
                }
                if (g[n + 1 - i][n + 1 - j] == 1) {
                    c[n + 1 - i][n + 1 - j] = c[n + 2 - i][n + 1 - j] + 1;
                    d[n + 1 - i][n + 1 - j] = d[n + 1 - i][n + 2 - j] + 1;
                }
            }
        }
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                ans = Math.max(ans, Math.min(Math.min(a[i][j], b[i][j]), Math.min(c[i][j], d[i][j])));
            }
        }
        return ans;
    }
}

C++ 代码:

C++ 复制代码
class Solution {
public:
    int orderOfLargestPlusSign(int n, vector<vector<int>>& mines) {
        vector<vector<int>> g(n + 10, vector<int>(n + 10, 1));
        for (vector<int>& info : mines) g[info[0] + 1][info[1] + 1] = 0;
        vector<vector<int>> a(n + 10, vector<int>(n + 10)), b(n + 10, vector<int>(n + 10)), c(n + 10, vector<int>(n + 10)), d(n + 10, vector<int>(n + 10));
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (g[i][j] == 1) {
                    a[i][j] = a[i - 1][j] + 1;
                    b[i][j] = b[i][j - 1] + 1;
                }
                if (g[n + 1 - i][n + 1 - j] == 1) {
                    c[n + 1 - i][n + 1 - j] = c[n + 2 - i][n + 1 - j] + 1;
                    d[n + 1 - i][n + 1 - j] = d[n + 1 - i][n + 2 - j] + 1;
                }
            }
        }
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                ans = max(ans, min(min(a[i][j], b[i][j]), min(c[i][j], d[i][j])));
            }
        }
        return ans;
    }
};

Python 代码:

Python 复制代码
class Solution:
    def orderOfLargestPlusSign(self, n: int, mines: List[List[int]]) -> int:
        g = [[1] * (n + 10) for _ in range(n + 10)]
        for x, y in mines:
            g[x + 1][y + 1] = 0
        a, b, c, d = [[0] * (n + 10) for _ in range(n + 10)], [[0] * (n + 10) for _ in range(n + 10)], [[0] * (n + 10) for _ in range(n + 10)], [[0] * (n + 10) for _ in range(n + 10)]
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                if g[i][j] == 1:
                    a[i][j] = a[i - 1][j] + 1
                    b[i][j] = b[i][j - 1] + 1
                if g[n + 1 - i][n + 1 - j] == 1:
                    c[n + 1 - i][n + 1 - j] = c[n + 2 - i][n + 1 - j] + 1
                    d[n + 1 - i][n + 1 - j] = d[n + 1 - i][n + 2 - j] + 1
        ans = 0
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                ans = max(ans, min(min(a[i][j], b[i][j]), min(c[i][j], d[i][j])))
        return ans

TypeScript 代码:

TypeScript 复制代码
function orderOfLargestPlusSign(n: number, mines: number[][]): number {
    function getMat(x: number, y: number, val: number): number[][] {
        const ans = new Array<Array<number>>(x)
        for (let i = 0; i < x; i++) ans[i] = new Array<number>(y).fill(val)
        return ans
    }
    const g = getMat(n + 10, n + 10, 1)
    for (const info of mines) g[info[0] + 1][info[1] + 1] = 0
    const a = getMat(n + 10, n + 10, 0), b = getMat(n + 10, n + 10, 0), c = getMat(n + 10, n + 10, 0), d = getMat(n + 10, n + 10, 0)
    for (let i = 1; i <= n; i++) {
        for (let j = 1; j <= n; j++) {
            if (g[i][j] == 1) {
                a[i][j] = a[i - 1][j] + 1
                b[i][j] = b[i][j - 1] + 1
            }
            if (g[n + 1 - i][n + 1 - j] == 1) {
                c[n + 1 - i][n + 1 - j] = c[n + 2 - i][n + 1 - j] + 1
                d[n + 1 - i][n + 1 - j] = d[n + 1 - i][n + 2 - j] + 1
            }
        }
    }
    let ans = 0
    for (let i = 1; i <= n; i++) {
        for (let j = 1; j <= n; j++) {
            ans = Math.max(ans, Math.min(Math.min(a[i][j], b[i][j]), Math.min(c[i][j], d[i][j])))
        }
    }
    return ans
}
  • 时间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n 2 ) O(n^2) </math>O(n2)
  • 空间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n 2 ) O(n^2) </math>O(n2)

我是宫水三叶,每天都会分享算法知识,并和大家聊聊近期的所见所闻。

欢迎关注,明天见。

相关推荐
喵叔哟21 分钟前
重构代码之取消临时字段
java·前端·重构
还是大剑师兰特1 小时前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解1 小时前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~1 小时前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding1 小时前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
man20171 小时前
【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
vue.js·spring boot·后端
阿征学IT1 小时前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓1 小时前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶21361 小时前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web
发现你走远了1 小时前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js