【华为机试真题详解 Java实现】带传送阵的矩阵游离【2023 Q1 考试题 A卷 | 200分】

这是一道华为面试的动态规划问题,要求从矩阵左上角走到右下角,经过的路径代价为相邻元素差的绝对值。允许使用一次传送阵,从一个数跳到相同数的位置,求最小代价。解题策略是用二维DP数组,考虑四种移动方向,并处理传送阵情况,时间复杂度O(nm^2),空间复杂度O(nm)。
摘要由CSDN通过智能技术生成

题目描述

【带传送阵的矩阵游离】

n 行 m 列的矩阵,每个位置上有一个元素。

你可以上下左右行走,代价是前后两个位置元素值差的绝对值。

另外,你最多可以使用一次传送阵(只能从一个数跳到另外一个相同的数),

求从走上角走到右下角最少需要多少时间。

解题思路

这是一个典型的动态规划问题。

我们可以定义一个二维数组 dp,其中 dp[i][j] 表示从左上角走到 (i, j) 位置的最小代价。初始时,dp[0][0] 的值为 0。

然后,我们考虑转移。从左上角到 (i, j) 可以有四种方式:从 (i-1, j) 向下走、从 (i, j-1) 向右走、从 (i+1, j) 向上走、从 (i, j+1) 向左走。但是,这里需要注意的是,如果我们使用了传送阵,那么从一个数跳到另外一个相同的数代价为 0,因此我们需要特殊处理这种情况。

具体地,我们可以枚举每一个位置 (i, j),对于每一个位置,我们计算出四种方式到达该位置的最小代价。如果存在传送阵,我们可以尝试使用传送阵到达该位置,这样可以省去一些代价。然后,从这四种方式中选择代价最小的一种作为从左上角到该位置的最小代价。最后,dp[n-1][m-1] 就是从左上角走到右下角的最小代价。
时间复杂度为 O(nm^2),空间复杂度为 O(nm)。

参考代码

public static int minCost(int[][] matrix) {
    int n = matrix.length, m = matrix[0].length;
    int[][] dp = new int[n][m];
    for (int i = 0; i < n; i++) {
        Arrays.fill(dp[i], Integer.MAX_VALUE);
    }
    dp[0][0] = 0;

    Map<Integer, int[]> teleport = new HashMap<>();
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            int[] pos = new int[]{i, j};
            teleport.put(matrix[i][j], pos);
            if (i > 0) {
                int cost = Math.abs(matrix[i][j] - matrix[i-1][j]);
                dp[i][j] = Math.min(dp[i][j], dp[i-1][j] + cost);
            }
            if (j > 0) {
                int cost = Math.abs(matrix[i][j] - matrix[i][j-1]);
                dp[i][j] = Math.min(dp[i][j], dp[i][j-1] + cost);
            }
            if (teleport.containsKey(matrix[i][j])) {
                int[] prevPos = teleport.get(matrix[i][j]);
                if (prevPos[0] != i || prevPos[1] != j) {
                    int cost = Math.abs(matrix[i][j] - matrix[prevPos[0]][prevPos[1]]);
                    dp[i][j] = Math.min(dp[i][j], dp[prevPos[0]][prevPos[1]] + cost);
                }
            }
        }
    }
    return dp[n-1][m-1];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值