程序员老鬼

35岁年薪百万,被95后领导逼到裸辞。。

今天我看到一个特别让人心塞的吐槽。

事情是这样的——一位年薪百万的35岁技术专家,居然被一个95后领导给逼到裸辞了。你没看错,就是95后,还是空降的那种。

Image

事情的导火索,是这位95后领导当面说:“你代码水平不如应届生,薪资倒挂合理,不想干可以走。” 这话说得真够生猛的,听得我差点把手里的咖啡洒了。

试想一下,一个年薪百万的技术大牛,被这么直接地戳到痛点,别说工作,连人设都要崩塌了。😱

有网友给了个“斗志满满”的建议:“为什么不想办法斗一斗,让他裁你呢?” 哎,没那么简单,毕竟这年头,领导不裁人,自己都很难保证能安稳做完项目。

Image

还有人说:“其实很多专家就是PPT写得好。” 我笑了,没错,PPT确实能掩盖很多东西,但技术这事,大家心里还是明白的。

Image

不管领导怎么说,最终的代码还是要靠手上的功夫说话。而且,真心希望那些95后能明白,年纪大不代表“过时”,但更不代表可以随便被忽视。技术无论多少年,都值得尊重。【备注:文末可领最新资料】。

算法题:铺瓷砖

今天我们来聊一聊一个经典的算法题——铺瓷砖。

给大家举个例子吧:假设你有一个长方形的地面,你需要用一些规格相同的正方形瓷砖铺满它。问题是,你能不能用最少的瓷砖数量来完成这个任务呢?说到这里,可能有同学觉得这个问题跟平常的编程题没什么关系,但你要知道,很多简单的现实问题背后都能映射出有趣的算法逻辑。

题目背景

我们有一个 m * n 的矩形地面,要用大小为 1 * 1 的正方形瓷砖去铺满这个矩形,问你最少需要多少个瓷砖才能铺满它。这里的一个核心要点是,铺瓷砖的时候不能让它们重叠,也不能铺出矩形的边界。

是不是听起来有点简单?但是,考虑到 m 和 n 的大小,以及不同的铺设方式,咱们得想想怎么能用最简洁有效的算法来解决它。别急,问题往往越简单,背后藏的技巧越深。

问题分析

其实这个问题可以分为两种情况:

  1. 如果 m 和 n 都是整除的,那答案就直接是 m * n,因为每个瓷砖的面积是 1,我们只需要铺满所有的区域就行。
  2. 如果 m 和 n 中有任何一个是奇数,那么就需要稍微复杂一点的算法来优化瓷砖的铺设。

其实,这个题目跟动态规划(Dynamic Programming)有点关系。你可以把它看作是一个分治问题。其实我们可以利用递归来解决它,思路是:如果当前的 m 和 n 都大于 1,那么你可以通过划分矩形,递归地求解每个小矩形的最小铺设量。

代码实现

好,既然我们说了这些,下面给大家提供一个 Java 实现的代码,来解决这个问题:

public class TilePaving {

    // 使用动态规划来解决铺瓷砖问题
    public int minTiles(int m, int n) {
        // 创建一个二维数组,用来保存中间计算结果,避免重复计算
        int[][] dp = new int[m + 1][n + 1];

        // 初始化dp数组,对于0x0的矩形铺设0个瓷砖
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                dp[i][j] = Integer.MAX_VALUE; // 初始化为最大值
            }
        }

                // 对于1x1的矩形,只需要1个瓷砖
        dp[1][1] = 1;

        // 递归计算每个子问题的最小瓷砖数量
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                // 横向拆分
                for (int k = 1; k <= i / 2; k++) {
                    dp[i][j] = Math.min(dp[i][j], dp[k][j] + dp[i - k][j]);
                }
                // 纵向拆分
                for (int k = 1; k <= j / 2; k++) {
                    dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[i][j - k]);
                }
            }
        }

        // 返回最终的最小瓷砖数
        return dp[m][n];
    }

    public static void main(String[] args) {
        TilePaving tp = new TilePaving();
        int result = tp.minTiles(4, 6);  // 举个例子:铺4x6的矩形地面
        System.out.println("最少需要瓷砖数量:" + result);  // 输出结果
    }
}

代码分析

首先,我们定义了一个 dp 数组,用来存储不同尺寸矩形的最小瓷砖数量。这里使用了二维数组,因为铺瓷砖的区域是一个矩形,只有 m 和 n 这两个维度需要考虑。初始化时,我们将 dp[1][1] = 1,意味着 1x1 的矩形只需要一个瓷砖。

接着,我们用双层循环遍历每个矩形区域的大小,尝试对其进行横向和纵向的拆分。每次拆分都会递归计算,直到最小的 1x1 瓷砖。

性能问题

有一个小问题是,这个算法的时间复杂度较高,接近 O(m * n),因为我们对每个矩形都进行一次拆分。而且我们通过递归计算,会有很多重复计算。为了提高效率,我们可以通过记忆化搜索(Memoization)来优化它,避免不必要的重复计算。

在算法的世界里,很多事情的解决都不是一步到位的,而是一步一步通过拆解、递归、迭代,甚至动态规划来逐步实现的。这种思维方式,也许就是我们程序员与其他人的最大不同吧。

-END-

ok,今天先说到这,老规矩,给大家分享一份不错的副业资料,感兴趣的同学找我领取。

图片

以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言。