力扣杯2023春-个人赛、战队赛

力扣杯2023春-个人赛

LCP 72. 补给马车

难度简单3

远征队即将开启未知的冒险之旅,不过在此之前,将对补给车队进行最后的检查。supplies[i] 表示编号为 i 的补给马车装载的物资数量。
考虑到车队过长容易被野兽偷袭,他们决定将车队的长度变为原来的一半(向下取整),计划为:

  • 找出车队中 物资之和最小 两辆 相邻 马车,将它们车辆的物资整合为一辆。若存在多组物资之和相同的马车,则取编号最小的两辆马车进行整合;
  • 重复上述操作直到车队长度符合要求。

请返回车队长度符合要求后,物资的分布情况。

示例 1:

输入:supplies = [7,3,6,1,8]

输出:[10,15]

解释:
第 1 次合并,符合条件的两辆马车为 6,1,合并后的车队为 [7,3,7,8];
第 2 次合并,符合条件的两辆马车为 (7,3) 和 (3,7),取编号最小的 (7,3),合并后的车队为 [10,7,8];
第 3 次合并,符合条件的两辆马车为 7,8,合并后的车队为 [10,15];
返回 [10,15]

示例 2:

输入:supplies = [1,3,1,5]

输出:[5,5]

解释:

  • 2 <= supplies.length <= 1000
  • 1 <= supplies[i] <= 1000

System.arraycopy():一般用于数组的复制和数据替换,是System类中一个被关键词native修饰的方法。

public static native void arraycopy(
    Object src, // 数据源,被复制的对象
    int  srcPos, // 复制起始坐标
    Object dest,  // 目标对象
 	int destPos, // 目标对象开始复制的起始点
 	int length // 复制的数据长度
 );

模拟

java

class Solution {
    public int[] supplyWagon(int[] supplies) {
        int m = supplies.length / 2; // 他们决定将车队的长度变为原来的一半(向下取整)
        for(int n = supplies.length; n > m; n--){
            int j = 1; // 用一个变量表示最小的相邻之和j-1和j
            for(int i = 1; i < n; i++){
                if(supplies[j] + supplies[j-1] > supplies[i] + supplies[i-1])
                    j = i;
            }
            // 合并j-1 和 j
            supplies[j-1] += supplies[j];
            System.arraycopy(supplies, j+1, supplies, j, n - 1 - j);
        }
        int[] res = new int[m];
        System.arraycopy(supplies, 0, res, 0, m);
        return res;
    }
}

python

class Solution:
    def supplyWagon(self, a: List[int]) -> List[int]:
        m = len(a) // 2
        while len(a) > m:
            idx = 1
            for i in range(1, len(a)):
                if a[i-1] + a[i] < a[idx - 1] + a[idx]:
                    idx = i
            a[idx - 1] += a[idx]
            a.pop(idx)
        return a

LCP 73. 探险营地

难度中等2

探险家小扣的行动轨迹,都将保存在记录仪中。expeditions[i] 表示小扣第 i 次探险记录,用一个字符串数组表示。其中的每个「营地」由大小写字母组成,通过子串 -> 连接。

例:“Leet->code->Campsite”,表示到访了 “Leet”、“code”、“Campsite” 三个营地。

expeditions[0] 包含了初始小扣已知的所有营地;对于之后的第 i 次探险(即 expeditions[i] 且 i > 0),如果记录中包含了之前均没出现的营地,则表示小扣 新发现 的营地。

请你找出小扣发现新营地最多且索引最小的那次探险,并返回对应的记录索引。如果所有探险记录都没有发现新的营地,返回 -1

注意:

  • 大小写不同的营地视为不同的营地;
  • 营地的名称长度均大于 0

示例 1:

输入:expeditions = ["leet->code","leet->code->Campsite->Leet","leet->code->leet->courier"]

输出:1

解释:
初始已知的所有营地为 “leet” 和 “code”
第 1 次,到访了 “leet”、“code”、“Campsite”、“Leet”,新发现营地 2 处:“Campsite”、“Leet”
第 2 次,到访了 “leet”、“code”、“courier”,新发现营地 1 处:“courier”
第 1 次探险发现的新营地数量最多,因此返回 1

示例 2:

输入:expeditions = ["Alice->Dex","","Dex"]

输出:-1

解释:
初始已知的所有营地为 “Alice” 和 “Dex”
第 1 次,未到访任何营地;
第 2 次,到访了 “Dex”,未新发现营地;
因为两次探险均未发现新的营地,返回 -1

示例 3:

输入:expeditions = ["","Gryffindor->Slytherin->Gryffindor","Hogwarts->Hufflepuff->Ravenclaw"]

输出:2

解释:
初始未发现任何营地;
第 1 次,到访 “Gryffindor”、“Slytherin” 营地,其中重复到访 “Gryffindor” 两次,
因此新发现营地为 2 处:“Gryffindor”、“Slytherin”
第 2 次,到访 “Hogwarts”、“Hufflepuff”、“Ravenclaw” 营地;
新发现营地 3 处:“Hogwarts”、“Hufflepuff”、“Ravenclaw”;
第 2 次探险发现的新营地数量最多,因此返回 2

提示:

  • 1 <= expeditions.length <= 1000
  • 0 <= expeditions[i].length <= 1000
  • 探险记录中只包含大小写字母和子串"->"

模拟 + 哈希

java

class Solution {
    public int adventureCamp(String[] expeditions) {
        Set<String> set = new HashSet<>();
        for(String s : expeditions[0].split("->"))
            set.add(s);
        int res = -1, maxcnt = 0;
        for(int i = 1; i < expeditions.length; i++){
            String exp = expeditions[i];
            if(exp.length() == 0) continue;
            int cnt = 0;
            for(String s : exp.split("->")){
                if(!set.contains(s)){
                    cnt++;
                    set.add(s);
                }
            }
            if(cnt > maxcnt){
                res = i;
                maxcnt = cnt;
            }
        }
        return res;
    }
}

python

class Solution:
    def adventureCamp(self, a: List[str]) -> int:
        vis = set(a[0].split('->'))
        max_cnt, ans = 0, -1
        for i in range(1, len(a)):
            if a[i] == "": continue
            cnt = 0
            for t in a[i].split('->'):
                if t not in vis:
                    vis.add(t)
                    cnt += 1
                if cnt > max_cnt:
                    max_cnt, ans = cnt, i
        return ans

LCP 74. 最强祝福力场

难度中等5

小扣在探索丛林的过程中,无意间发现了传说中“落寞的黄金之都”。而在这片建筑废墟的地带中,小扣使用探测仪监测到了存在某种带有「祝福」效果的力场。
经过不断的勘测记录,小扣将所有力场的分布都记录了下来。forceField[i] = [x,y,side] 表示第 i 片力场将覆盖以坐标 (x,y) 为中心,边长为 side 的正方形区域。

若任意一点的 力场强度 等于覆盖该点的力场数量,请求出在这片地带中 力场强度 最强处的 力场强度

注意:

  • 力场范围的边缘同样被力场覆盖。

示例 1:

输入:
forceField = [[0,0,1],[1,0,1]]

输出:2

解释:如图所示,(0.5, 0) 处力场强度最强为 2, (0.5,-0.5)处力场强度同样是 2。
image.png

示例 2:

输入:
forceField = [[4,4,6],[7,5,3],[1,6,2],[5,6,3]]

输出:3

解释:如下图所示,
forceField[0]、forceField[1]、forceField[3] 重叠的区域力场强度最大,返回 3
image.png

提示:

  • 1 <= forceField.length <= 100
  • forceField[i].length == 3
  • 0 <= forceField[i][0], forceField[i][1] <= 10^9
  • 1 <= forceField[i][2] <= 10^9

二维差分 + 离散化

https://leetcode.cn/problems/xepqZ5/solution/chi-san-hua-er-wei-chai-fen-by-endlessch-q43z/

class Solution:
    def fieldOfGreatestBlessing(self, forceField: List[List[int]]) -> int:
        # 二维更新问题:通用做法,二维差分
        # 要求返回每个点覆盖多少次

        # 点存在0.5 : 把横纵坐标 * 2
        # 1e9数据范围:离散化(可以用map,也可用在排序后的数组中使用二分查找)

        # 1. 统计所有左下和右上坐标
        x_set = set()
        y_set = set()
        for i, j, side in forceField:
            x_set.add(2 * i - side) # 左横坐标 (i - side/2) * 2
            x_set.add(2 * i + side) # 右横坐标
            y_set.add(2 * j - side) # 下纵坐标
            y_set.add(2 * j + side) # 上纵坐标

        # 2. 离散化
        xs = sorted(x_set) # 将横纵坐标排序,方便离散化
        ys = sorted(y_set)
        n, m = len(xs), len(ys)
        
        # 3. 二维差分:快速地把一个矩形范围内的数都 +1
        diff = [[0] * (m+2) for _ in range(n+2)]
        for i, j, side in forceField:
            r1 = bisect_left(xs, 2*i-side) # 离散化后的左横坐标
            r2 = bisect_left(xs, 2*i+side) # 离散化后的右横坐标
            c1 = bisect_left(ys, 2*j-side) # 离散化后的下纵坐标
            c2 = bisect_left(ys, 2*j+side) # 离散化后的上纵坐标
            # 将区域 r1<=r<=r2 && c1<=c<=c2 上的数都加上 x
            # 多 +1 是为了方便求后面用二维前缀和复原,不加1的话需要在后面复原时i,j+1(同二维数组方式)
            diff[r1 + 1][c1 + 1] += 1 
            diff[r1 + 1][c2 + 2] -= 1
            diff[r2 + 2][c1 + 1] -= 1
            diff[r2 + 2][c2 + 2] += 1

        # 4. 直接在 diff 上复原(二维前缀和),计算最大值
        ans = 0
        for i in range(1, n+1):
            for j in range(1, m+1):
                diff[i][j] += diff[i][j - 1] + diff[i - 1][j] - diff[i - 1][j - 1]
                ans = max(ans, diff[i][j])
        return ans 

扫描线


LCP 75. 传送卷轴

难度困难5

随着不断的深入,小扣来到了守护者之森寻找的魔法水晶。首先,他必须先通过守护者的考验。

考验的区域是一个正方形的迷宫,maze[i][j] 表示在迷宫 ij 列的地形:

  • 若为 . ,表示可以到达的空地;
  • 若为 # ,表示不可到达的墙壁;
  • 若为 S ,表示小扣的初始位置;
  • 若为 T ,表示魔法水晶的位置。

小扣每次可以向 上、下、左、右 相邻的位置移动一格。而守护者拥有一份「传送魔法卷轴」,使用规则如下:

  • 魔法需要在小扣位于 空地 时才能释放,发动后卷轴消失;;
  • 发动后,小扣会被传送到水平或者竖直的镜像位置,且目标位置不得为墙壁(如下图所示);
    image.png

在使用卷轴后,小扣将被「附加负面效果」,因此小扣需要尽可能缩短传送后到达魔法水晶的距离。而守护者的目标是阻止小扣到达魔法水晶的位置;如果无法阻止,则尽可能 增加 小扣传送后到达魔法水晶的距离。
假设小扣和守护者都按最优策略行事,返回小扣需要在 「附加负面效果」的情况下 最少 移动多少次才能到达魔法水晶。如果无法到达,返回 -1

注意:

  • 守护者可以不使用卷轴;
  • 传送后的镜像位置可能与原位置相同。

示例 1:

输入:maze = [".....","##S..","...#.","T.#..","###.."]

输出:7

解释:如下图所示:
守护者释放魔法的两个最佳的位置为 [2,0] 或 [3,1]:
若小扣经过 [2,0],守护者在该位置释放魔法,
小扣被传送至 [2,4] 处且加上负面效果,此时小扣还需要移动 7 次才能到达魔法水晶;
若小扣经过 [3,1],守护者在该位置释放魔法,
小扣被传送至 [3,3] 处且加上负面效果,此时小扣还需要移动 9 次才能到达魔法水晶;
因此小扣负面效果下最少需要移动 7 次才能到达魔法水晶。
image.png

示例 2:

输入:maze = [".#..","..##",".#S.",".#.T"]

输出:-1

解释:如下图所示。
若小扣向下移动至 [3,2],守护者使其传送至 [0,2],小扣将无法到达魔法水晶;
若小扣向右移动至 [2,3],守护者使其传送至 [2,0],小扣将无法到达魔法水晶;
image.png

示例 3:

输入:maze = ["S###.","..###","#..##","##..#","###.T"]

输出:5

解释:如下图所示:
守护者需要小扣在空地才能释放,因此初始无法将其从 [0,0] 传送至 [0,4];
当小扣移动至 [2,1] 时,释放卷轴将其传送至水平方向的镜像位置 [2,1](为原位置)
而后小扣需要移动 5 次到达魔法水晶
image.png

提示:

  • 4 <= maze.length == maze[i].length <= 200
  • maze[i][j] 仅包含 ".""#""S""T"
class Solution:
    """
    什么时候 -1?
    1. 本来就无法到达终点
    2. 无论怎么走,都会被传送到一个无法到达终点的位置

    能不能二分答案?maxDis limit
    为什么可以二分?

    走到一个位置(陷阱) ,传送之后还需要走 > maxDis 步
        如果在不走 # 不走陷阱的情况下,可以到达终点 => 答案 <= maxDis
        如果无法到达终点 => 答案 > maxDis
    答案有单调性,可以二分

    怎么快速判断是否为陷阱:求出终点到其余点的最短路(求各点到终点的最短路不好求,正难则反)


    """
    def challengeOfTheKeeper(self, maze: List[str]) -> int:
        m, n = len(maze), len(maze[0])

        # 1. 找 S T的位置
        for i, row in enumerate(maze):
            for j, c in enumerate(row):
                if c == 'S':
                    sx, sy = i, j
                elif c == 'T':
                    tx, ty = i, j
        
        # 2. BFS求终点到其余点的最短路的长度
        dis_from_t = [[inf] * n for _ in range(m)]
        dis_from_t[tx][ty] = 0
        q = [(tx, ty)]
        step = 1
        while q:
            nxt = []
            for i, j in q:
                for x, y in (i+1, j), (i-1, j), (i, j+1), (i, j-1):
                    if 0 <= x < m and 0 <= y < n and maze[x][y] != '#' and dis_from_t[x][y] == inf:
                        dis_from_t[x][y] = step
                        nxt.append((x, y))
            q = nxt
            step += 1
        
        # 3. 剪枝,如果S无法到达T,直接返回 -1
        if dis_from_t[sx][sy] == inf:
            return -1

        # 4. 二分答案
        vis = [[-1] * n for _ in range(m)]
        def check(max_dis: int) -> bool:
            # DFS,看能否在「附加负面效果」的情况下,移动不超过 max_dis 步到达终点
            def dfs(i: int, j: int) -> bool:
                if i < 0 or i >= m or j < 0 or j >= n or vis[i][j] == max_dis or maze[i][j] == '#':
                    return False
                if maze[i][j] == 'T':  # 到达终点
                    return True
                
                vis[i][j] = max_dis  # 为避免反复创建 vis,用一个每次二分都不一样的数来标记
                # 守护者使用卷轴传送小扣,如果小扣无法在 maxDis 步内到达终点,则返回 false

                # maze[i][n - 1 - j]和maze[m - 1 - i][j] 是 陷阱位置 且 最后不能走到t,return false
                if maze[i][j] == '.' and \
                   (maze[i][n - 1 - j] != '#' and dis_from_t[i][n - 1 - j] > max_dis or
                    maze[m - 1 - i][j] != '#' and dis_from_t[m - 1 - i][j] > max_dis):
                    return False
                for x, y in (i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1):
                    if dfs(x, y):
                        return True
                return False
            return dfs(sx, sy) # 从起点开始走看能不能在移动不超过max_ids步的前提下到达终点
        
        ans = bisect_left(range(m * n + 1), True, key=check)
        return -1 if ans > m * n else ans

LCP 76. 魔法棋盘

难度困难0

在大小为 n * m 的棋盘中,有两种不同的棋子:黑色,红色。当两颗颜色不同的棋子同时满足以下两种情况时,将会产生魔法共鸣:

  • 两颗异色棋子在同一行或者同一列

  • 两颗异色棋子之间恰好只有一颗棋子

    注:异色棋子之间可以有空位

由于棋盘上被施加了魔法禁制,棋盘上的部分格子变成问号。chessboard[i][j] 表示棋盘第 ij 列的状态:

  • 若为 . ,表示当前格子确定为空
  • 若为 B ,表示当前格子确定为 黑棋
  • 若为 R ,表示当前格子确定为 红棋
  • 若为 ? ,表示当前格子待定

现在,探险家小扣的任务是确定所有问号位置的状态(留空/放黑棋/放红棋),使最终的棋盘上,任意两颗棋子间都 无法 产生共鸣。请返回可以满足上述条件的放置方案数量。

示例1:

输入:n = 3, m = 3, chessboard = ["..R","..B","?R?"]

输出:5

解释:给定的棋盘如图:
image.png
所有符合题意的最终局面如图:
image.png

示例2:

输入:n = 3, m = 3, chessboard = ["?R?","B?B","?R?"]

输出:105

提示:

  • n == chessboard.length
  • m == chessboard[i].length
  • 1 <= n*m <= 30
  • chessboard 中仅包含 "."、"B"、"R"、"?"

不会.jpg
的状态(留空/放黑棋/放红棋),使最终的棋盘上,任意两颗棋子间都 无法 产生共鸣。请返回可以满足上述条件的放置方案数量。

示例1:

输入:n = 3, m = 3, chessboard = ["..R","..B","?R?"]

输出:5

解释:给定的棋盘如图:
[外链图片转存中…(img-MjLgrXnq-1682760441407)]
所有符合题意的最终局面如图:
[外链图片转存中…(img-ADKaCrLh-1682760441408)]

示例2:

输入:n = 3, m = 3, chessboard = ["?R?","B?B","?R?"]

输出:105

提示:

  • n == chessboard.length
  • m == chessboard[i].length
  • 1 <= n*m <= 30
  • chessboard 中仅包含 "."、"B"、"R"、"?"

不会.jpg

力扣杯2023春·战队赛

力扣杯春赛战队赛讨论贴:https://leetcode.cn/circle/discuss/cyG1Ea/

LCP 77. 符文储备

难度简单2

远征队在出发前需要携带一些「符文」,作为后续的冒险储备。runes[i] 表示第 i 枚符文的魔力值。

他们将从中选取若干符文进行携带,并对这些符文进行重新排列,以确保任意相邻的两块符文之间的魔力值相差不超过 1

请返回他们能够携带的符文 最大数量

示例 1:

输入:runes = [1,3,5,4,1,7]

输出:3

解释:最佳的选择方案为[3,5,4]
将其排列为 [3,4,5] 后,任意相邻的两块符文魔力值均不超过 1,携带数量为 3
其他满足条件的方案为 [1,1] 和 [7],数量均小于 3。
因此返回可携带的最大数量 3

示例 2:

输入:runes = [1,1,3,3,2,4]

输出:6

解释:排列为 [1,1,2,3,3,4],可携带所有的符文

提示:

  • 1 <= runes.length <= 10^4
  • 0 <= runes[i] <= 10^4

模拟

排序 + 遍历:类似求最长连续子数组问题(简单DP问题)

  • 如果当前符文和前一个符文的魔力值差不超过1,则将当前符文加入选中的符文中
  • 否则就重新开始选符文
  • 遍历的同时更新最大值
class Solution {
    public int runeReserve(int[] runes) {
        Arrays.sort(runes);
        int n = runes.length;
        int[] f = new int[n+1];
        Arrays.fill(f, 1);
        int ans = 0;
        for(int i = 0; i < n-1; i++){
            if(runes[i+1] - runes[i] <= 1)
                f[i+1] = f[i] + 1;
            ans = Math.max(f[i+1], ans);
        }
        return ans;
    }
}

LCP 78. 城墙防线

难度中等2

在探险营地间,小扣意外发现了一片城墙遗迹,在探索期间,却不巧遇到迁徙中的兽群向他迎面冲来。情急之下小扣吹响了他的苍蓝笛,随着笛声响起,遗迹中的城墙逐渐发生了横向膨胀。
已知 rampart[i] = [x,y] 表示第 i 段城墙的初始所在区间。当城墙发生膨胀时,将遵循以下规则:

  • 所有的城墙会同时膨胀相等的长度;
  • 每个城墙可以向左、向右或向两个方向膨胀。

小扣为了确保自身的安全,需要在所有城墙均无重叠的情况下,让城墙尽可能的膨胀。请返回城墙可以膨胀的 最大值

注意:

  • 初始情况下,所有城墙均不重叠,且 rampart 中的元素升序排列;
  • 两侧的城墙可以向外无限膨胀。

示例 1:

输入:rampart = [[0,3],[4,5],[7,9]]

输出:3

解释:如下图所示:
rampart[0] 向左侧膨胀 3 个单位;
rampart[2] 向右侧膨胀 3 个单位;
rampart[1] 向左侧膨胀 1 个单位,向右膨胀 2 个单位。
不存在膨胀更多的方案,返回 3。
image.png

示例 2:

输入:rampart = [[1,2],[5,8],[11,15],[18,25]]

输出:4

提示:

  • 3 <= rampart.length <= 10^4
  • rampart[i].length == 2
  • 0 <= rampart[i][0] < rampart[i][1] <= rampart[i+1][0] <= 10^8

二分答案 + 贪心

贪心,每段城墙先向左膨胀,再向右膨胀,如果超过右侧的城墙则说明答案过大。如果都可以膨胀,则继续二分更大的答案。

class Solution {
    public int rampartDefensiveLine(int[][] rampart) {
        //二分答案,如果可以膨胀k,那么膨胀k-1也是符合的
        int left = 0, right = (int)1e9;
        while(left < right){
            int mid = (left + right + 1) >> 1;
            if(!check(mid, rampart)) right = mid - 1;
            else left = mid;
        }
        return right;
    }
    
    // 返回每个城墙能否膨胀m
    public boolean check(int m, int[][] rampart){
        int right = rampart[0][1];
        for(int i = 1; i < rampart.length; i++){
            int l = rampart[i][0], r = rampart[i][1];
            if(right > l) return false;
            int tmp = l - right;
            if(tmp > m) right = r;
            else
                right = r + (m - tmp);
        }
        return true;
    }
}

LCP 79. 提取咒文

难度中等1

随着兽群逐渐远去,一座大升降机缓缓的从地下升到了远征队面前。借由这台升降机,他们将能够到达地底的永恒至森。
在升降机的操作台上,是一个由魔法符号组成的矩阵,为了便于辨识,我们用小写字母来表示。 matrix[i][j] 表示矩阵第 ij 列的字母。该矩阵上有一个提取装置,可以对所在位置的字母提取。
提取装置初始位于矩阵的左上角 [0,0],可以通过每次操作移动到上、下、左、右相邻的 1 格位置中。提取装置每次移动或每次提取均记为一次操作。

远征队需要按照顺序,从矩阵中逐一取出字母以组成 mantra,才能够成功的启动升降机。请返回他们 最少 需要消耗的操作次数。如果无法完成提取,返回 -1

注意:

  • 提取装置可对同一位置的字母重复提取,每次提取一个
  • 提取字母时,需按词语顺序依次提取

示例 1:

输入:matrix = ["sd","ep"], mantra = "speed"

输出:10

解释:如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gWVubLSh-1683528317420)(https://pic.leetcode-cn.com/1646288670-OTlvAl-%E7%9F%A9%E9%98%B5%20(2)].gif)

示例 2:

输入:matrix = ["abc","daf","geg"], mantra = "sad"

输出:-1

解释:矩阵中不存在 s ,无法提取词语

提示:

  • 0 < matrix.length, matrix[i].length <= 100
  • 0 < mantra.length <= 100
  • matrix 和 mantra 仅由小写字母组成

三维BFS

class Solution {
    private int[][] dirs = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    public int extractMantra(String[] matrix, String mantra) {
        int n = matrix.length, m = matrix[0].length(), k = mantra.length();
        //记录已经访问过的状态
        boolean[][][] visited = new boolean[n][m][k];
        Deque<int[]> dq = new ArrayDeque<>();
        dq.add(new int[]{0, 0, 0}); // i, j, k
        visited[0][0][0] = true;
        int step = 1;
        while(!dq.isEmpty()){
            int size = dq.size();
            while(size-- > 0){
                int[] curpos = dq.pollFirst();
                //如果当前位置的字符和目标字符串中的字符一致,取一下并且把下一个字符放入队列
                if(matrix[curpos[0]].charAt(curpos[1]) == mantra.charAt(curpos[2])){
                    if(curpos[2] == k-1)
                        return step;
                    else
                        dq.addLast(new int[]{curpos[0], curpos[1], curpos[2] + 1});
                }else{
                    // 往四个方向查找
                    for(int[] d : dirs){
                        int newx = curpos[0] + d[0], newy = curpos[1] + d[1];
                        if(newx >= 0 && newx < n && newy >= 0 && newy < m && !visited[newx][newy][curpos[2]]){
                            visited[newx][newy][curpos[2]] = true;
                            dq.addLast(new int[]{newx, newy, curpos[2]});
                        }
                    }
                }
            }
            step += 1;
        }
        return -1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值