中等题 小U的最大连续移动次数问题 |豆包MarsCode AI 刷题

197 阅读2分钟

小U的最大连续移动次数问题(刷题笔记)

问题描述

问题描述

小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:

  1. 只能上坡或者下坡,不能走到高度相同的点。
  2. 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
  3. 每个位置只能经过一次,不能重复行走。

任务是帮助小U找到他在地图上可以移动的最大次数,即在符合所有条件的前提下,小U能走过的最大连续位置数量。

例如在以下2x2的地图中:

1 2
4 3

中庸行者可以选择移动顺序 3 -> 4 -> 1 -> 2,最大移动次数为3。

解题思路

1.创建一个布尔数组visited记录每个位置的访问情况 2.DFS深度搜索:根据当前位置和先前位置决定上坡和下坡,用递归实现

代码

public class Main {
    public static int solution(int m, int n, int[][] a) {
        // write code here
        boolean[][] visited = new boolean[m][n];
        int maxMoves = 0;
        if (m == 1 && n == 1) {
            return 0;
        }
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                maxMoves = Math.max(maxMoves, DFS(i, j, a, visited, 0, true) - 1);
                maxMoves = Math.max(maxMoves,DFS(i, j, a, visited,Integer.MAX_VALUE, false)-1);
            }
        }
        System.out.println(maxMoves);

        return maxMoves ;
    }

    public static int DFS(int x, int y, int[][] a, boolean[][] visited, int pHeight, boolean isUp) {
        int cHeight = a[x][y];
        if (x < 0 || x >= a.length || y < 0 || y >= a[0].length || visited[x][y] || cHeight == pHeight) {
            return 0;
        }
        visited[x][y] = true;
        int moves = 0;
        // System.out.println("Visiting (" + x + ", " + y + ") with height " + cHeight);
        int[][] directions = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
        for (int[] direction : directions) {
            int nextX = x + direction[0];
            int nextY = y + direction[1];
            boolean b = !(nextX >= a.length || nextX < 0 || nextY >= a[0].length || nextY < 0);
            if (isUp && cHeight > pHeight) {
                if (b ) {
                    moves = Math.max(moves, 1 + DFS(nextX, nextY, a, visited, cHeight, false));
                }

            } else if (!isUp && cHeight < pHeight) {
                if (b ) {
                    moves = Math.max(moves, 1 + DFS(nextX, nextY, a, visited, cHeight, true));
                }

            }

        }
        visited[x][y] = false;
        return moves;
    }

    public static void main(String[] args) {
        System.out.println(solution(2, 2, new int[][] { { 1, 2 }, { 4, 3 } }) == 3);
        System.out.println(solution(3, 3, new int[][] { { 10, 1, 6 }, { 5, 9, 3 }, { 7, 2, 4 } }) == 8);
        System.out.println(solution(4, 4,
                new int[][] { { 8, 3, 2, 1 }, { 4, 7, 6, 5 }, { 12, 11, 10, 9 }, { 16, 15, 14, 13 } }) == 11);
    }
}

总结

1.遇到给定地图的二维数组,可以联想到DFS或BFS的遍历方式 2. DFS的递归调用:在DFS中,根据当前位置的高度和前一个位置的高度,决定下一步是上坡还是下坡。 3. 回溯:在DFS结束后,需要将当前位置标记为未访问,以便其他路径可以再次访问该位置。 4. 边界条件:在DFS中,需要检查下一个位置是否在地图范围内,并且不能重复访问同一个位置。

2024.11.17刷题记录