欢迎光临
我们一直在努力

华为OD 2026机试真题 Java&Go 语言实现【自动泊车】

一、题目

题目描述:

在某商场的地下停车场,部署了一套智能导航系统。停车场可以看作是一个 r × c 的网格矩阵,其中:

  • 0 表示该位置是空的行车道,车辆可以通行。
  • 1 表示该位置存有障碍物、立柱或其他已停放的车辆,车辆无法通行。

停车场的入口统一设在坐标 [0, 0] 处。现在有一辆车进入停车场,需要前往指定的目标车位 [m, n]。

车辆在停车场内只能沿着上、下、左、右四个方向移动,每移动一个格子计为步数 1。请你帮车主规划一条从入口到目标车位的最短路径。

📥 输入描述

  • 第一行输入两个整数 m 和 n,表示目标车位的行下标和列下标。
  • 第二行输入两个整数 row 和 col,表示停车场的总行数和总列数。
  • 接下来的 row 行,每行包含 col 个以空格分隔的整数(0 或 1),表示停车场的状态信息。

  • ⚠️ 约束条件

    • 1 < row, col < 200
    • 0 < m < row, 0 < n < col
    • 入口 [0, 0] 保证为空位(即值为 0)

    📤 输出描述

    • 输出一个整数,表示从入口 [0, 0] 到目标车位 [m, n] 的最短路径步数。
    • 如果由于障碍物阻挡无法到达目标位置,则输出 -1。

    🧪 示例 1

    输入:

    1 1
    3 3
    0 0 0
    0 0 0
    0 0 0

    输出:2

    说明:

    停车场大小为 3×3,目标位置在 [1, 1]。
    最短路径序列可为:[0, 0] → [0, 1] → [1, 1],共移动 2 步。
    或者:[0, 0] → [1, 0] → [1, 1],共移动 2 步。


    🧪 示例 2

    输入:

    2 2
    3 3
    0 1 0
    1 1 0
    0 0 0

    输出:-1

    说明:

    由于入口[0,0]的右边[0,1]和下边[1,0]均为障碍物(1),车辆被困在入口处,无法到达目标位置[2,2],因此输出-1。

    🧪 示例 3

    输入:

    0 2
    3 3
    0 0 0
    1 1 0
    0 0 0

    输出:2

    说明:

    目标位置在 [0, 2]。虽然中间有障碍物,但可以沿着第一行直接向右行驶:[0, 0] → [0, 1] → [0, 2],步数为 2。

    这是一道经典的 网格最短路径问题,本质是 BFS(广度优先搜索) 的应用。题目要求在 r×c 的网格中,从起点 [0, 0] 到终点 [m, n],只能上下左右移动,避开障碍物(值为1),求最少步数;若不可达则返回 -1。


    二、解题思路

    🎯 核心思想:BFS(广度优先搜索)

    • BFS 天然适合求“无权图”的最短路径。
    • 每次扩展一层邻居节点,第一次到达目标点时的步数即为最小步数。
    • 使用队列存储待访问的坐标 (row, col) 和当前步数。
    • 使用 visited 数组或原地标记避免重复访问。

    🧭 步骤分解:

  • 输入解析

    • 读取目标位置 m, n
    • 读取网格尺寸 row, col
    • 读取 row × col 的网格矩阵
  • 边界检查

    • 起点 [0,0] 保证为空(题目已给)
    • 若目标位置是障碍物 → 直接返回 -1
  • BFS 初始化

    • 创建队列,初始加入 (0, 0, 0) —— 表示从 (0,0) 出发,走了 0 步
    • 创建 visited 二维数组,标记已访问位置,防止死循环
  • BFS 循环

    • 出队一个位置 (r, c, steps)
    • 如果 (r, c) == (m, n) → 返回 steps
    • 否则,尝试四个方向:上、下、左、右
      • 新位置 (nr, nc) 需在范围内
      • 且不是障碍物(grid[nr][nc] == 0)
      • 且未被访问过
      • 满足条件则入队,并标记为已访问
  • 结束判断

    • 队列空仍未找到目标 → 返回 -1

  • 三、Code实现

    1、Java✅

    import java.util.*;

    public class ParkingNavigation {
    public static int shortestPath(int m, int n, int row, int col, int[][] grid) {
    // 目标位置是障碍物,直接返回 -1
    if (grid[m][n] == 1) return -1;

    // 方向数组:上、下、左、右
    int[] dr = {-1, 1, 0, 0};
    int[] dc = {0, 0, -1, 1};

    // visited 数组记录是否访问过
    boolean[][] visited = new boolean[row][col];
    Queue<int[]> queue = new LinkedList<>();

    // 起始点 [0,0] 入队,步数为 0
    queue.offer(new int[]{0, 0, 0});
    visited[0][0] = true;

    while (!queue.isEmpty()) {
    int[] curr = queue.poll();
    int r = curr[0], c = curr[1], steps = curr[2];

    // 到达目标
    if (r == m && c == n) {
    return steps;
    }

    // 探索四个方向
    for (int i = 0; i < 4; i++) {
    int nr = r + dr[i];
    int nc = c + dc[i];

    // 检查边界、障碍物、是否访问过
    if (nr >= 0 && nr < row && nc >= 0 && nc < col
    && grid[nr][nc] == 0 && !visited[nr][nc]) {
    visited[nr][nc] = true;
    queue.offer(new int[]{nr, nc, steps + 1});
    }
    }
    }

    // 无法到达
    return -1;
    }

    // 测试主函数
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int m = sc.nextInt();
    int n = sc.nextInt();
    int row = sc.nextInt();
    int col = sc.nextInt();

    int[][] grid = new int[row][col];
    for (int i = 0; i < row; i++) {
    for (int j = 0; j < col; j++) {
    grid[i][j] = sc.nextInt();
    }
    }

    System.out.println(shortestPath(m, n, row, col, grid));
    }
    }


    2、Go✅

    package main

    import (
    "bufio"
    "fmt"
    "os"
    )

    func shortestPath(m, n, row, col int, grid [][]int) int {
    // 目标位置是障碍物,直接返回 -1
    if grid[m][n] == 1 {
    return -1
    }

    // 方向数组:上、下、左、右
    dr := []int{-1, 1, 0, 0}
    dc := []int{0, 0, -1, 1}

    // visited 数组
    visited := make([][]bool, row)
    for i := range visited {
    visited[i] = make([]bool, col)
    }

    // 队列:每个元素是 [r, c, steps]
    queue := [][]int{{0, 0, 0}}
    visited[0][0] = true

    for len(queue) > 0 {
    curr := queue[0]
    queue = queue[1:]
    r, c, steps := curr[0], curr[1], curr[2]

    // 到达目标
    if r == m && c == n {
    return steps
    }

    // 探索四个方向
    for i := 0; i < 4; i++ {
    nr := r + dr[i]
    nc := c + dc[i]

    // 检查边界、障碍物、是否访问过
    if nr >= 0 && nr < row && nc >= 0 && nc < col &&
    grid[nr][nc] == 0 && !visited[nr][nc] {
    visited[nr][nc] = true
    queue = append(queue, []int{nr, nc, steps + 1})
    }
    }
    }

    // 无法到达
    return -1
    }

    func main() {
    scanner := bufio.NewScanner(os.Stdin)

    var m, n, row, col int
    fmt.Scan(&m, &n)
    fmt.Scan(&row, &col)

    grid := make([][]int, row)
    for i := 0; i < row; i++ {
    grid[i] = make([]int, col)
    for j := 0; j < col; j++ {
    fmt.Scan(&grid[i][j])
    }
    }

    result := shortestPath(m, n, row, col, grid)
    fmt.Println(result)
    }


    四、复杂度分析

    指标说明
    时间复杂度 O(row × col) —— 每个格子最多访问一次
    空间复杂度 O(row × col) —— visited 数组 + 队列最大长度

    🎯 总结一句话

    “本题是标准 BFS 应用题,关键是正确建模网格、控制边界、避免重复访问,首次抵达目标即得最短路径。”

    祝你面试顺利,代码一遍 AC!🚀

    赞(0)
    未经允许不得转载:171主机测评 » 华为OD 2026机试真题 Java&Go 语言实现【自动泊车】
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址