news 2026/8/22 11:11:35

DeepSeek LintCode 258 · 地图跳跃 public int mapJump(int[][] arr)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek LintCode 258 · 地图跳跃 public int mapJump(int[][] arr)

我来为你详细分析 LintCode 258 题「地图跳跃」的解法。

题目理解

题目描述

  • 给定一个二维数组arr,每个位置有一个高度值
  • 从左上角(0,0)出发,要到达右下角(n-1, m-1)
  • 可以向上、下、左、右四个方向移动
  • 每次跳跃的高度差不能超过k(k 是需要求解的最小值)
  • 求能够到达终点的最小k

解题思路

这是一个典型的最小值最大化问题,可以用二分答案 + BFS/DFS 验证来解决。

算法思路

  1. 二分查找可能的 k 值范围

    • 最小可能:0(所有格子高度相同)
    • 最大可能:max(arr) - min(arr)(最大高度差)
  2. 验证函数:对于给定的 k,判断是否能从起点走到终点

    • 使用 BFS 或 DFS 遍历
    • 只允许走高度差 ≤ k 的相邻格子

代码实现

解法一:二分查找 + BFS

publicclassSolution{/** * @param arr: the height map * @return: the minimum k */publicintmapJump(int[][]arr){if(arr==null||arr.length==0||arr[0].length==0){return0;}intn=arr.length;intm=arr[0].length;// 找到地图中的最小和最大高度intminHeight=Integer.MAX_VALUE;intmaxHeight=Integer.MIN_VALUE;for(inti=0;i<n;i++){for(intj=0;j<m;j++){minHeight=Math.min(minHeight,arr[i][j]);maxHeight=Math.max(maxHeight,arr[i][j]);}}// 二分查找最小的 kintleft=0;intright=maxHeight-minHeight;while(left+1<right){intmid=left+(right-left)/2;if(canReach(arr,mid)){right=mid;}else{left=mid;}}// 先检查 left,再检查 rightif(canReach(arr,left)){returnleft;}returnright;}// BFS 验证是否能以最大高度差 k 到达终点privatebooleancanReach(int[][]arr,intk){intn=arr.length;intm=arr[0].length;// 四个方向:上、下、左、右int[][]dirs={{-1,0},{1,0},{0,-1},{0,1}};boolean[][]visited=newboolean[n][m];Queue<int[]>queue=newLinkedList<>();// 从起点开始queue.offer(newint[]{0,0});visited[0][0]=true;while(!queue.isEmpty()){int[]curr=queue.poll();intx=curr[0];inty=curr[1];// 到达终点if(x==n-1&&y==m-1){returntrue;}// 尝试四个方向for(int[]dir:dirs){intnx=x+dir[0];intny=y+dir[1];// 检查边界if(nx<0||nx>=n||ny<0||ny>=m){continue;}// 检查是否访问过if(visited[nx][ny]){continue;}// 检查高度差是否在允许范围内intheightDiff=Math.abs(arr[nx][ny]-arr[x][y]);if(heightDiff>k){continue;}visited[nx][ny]=true;queue.offer(newint[]{nx,ny});}}returnfalse;}}

解法二:二分查找 + DFS

publicclassSolution{privateint[][]dirs={{-1,0},{1,0},{0,-1},{0,1}};privateintn,m;privateint[][]arr;publicintmapJump(int[][]arr){if(arr==null||arr.length==0||arr[0].length==0){return0;}this.arr=arr;this.n=arr.length;this.m=arr[0].length;// 找到高度范围intminH=arr[0][0],maxH=arr[0][0];for(inti=0;i<n;i++){for(intj=0;j<m;j++){minH=Math.min(minH,arr[i][j]);maxH=Math.max(maxH,arr[i][j]);}}// 二分查找intleft=0,right=maxH-minH;while(left<right){intmid=left+(right-left)/2;if(canReach(mid)){right=mid;}else{left=mid+1;}}returnleft;}privatebooleancanReach(intk){boolean[][]visited=newboolean[n][m];returndfs(0,0,k,visited);}privatebooleandfs(intx,inty,intk,boolean[][]visited){// 到达终点if(x==n-1&&y==m-1){returntrue;}visited[x][y]=true;// 尝试四个方向for(int[]dir:dirs){intnx=x+dir[0];intny=y+dir[1];if(nx<0||nx>=n||ny<0||ny>=m||visited[nx][ny]){continue;}if(Math.abs(arr[nx][ny]-arr[x][y])<=k){if(dfs(nx,ny,k,visited)){returntrue;}}}returnfalse;}}

解法三:并查集(Union Find)

publicclassSolution{classUnionFind{int[]parent;UnionFind(intn){parent=newint[n];for(inti=0;i<n;i++){parent[i]=i;}}intfind(intx){if(parent[x]!=x){parent[x]=find(parent[x]);}returnparent[x];}voidunion(intx,inty){introotX=find(x);introotY=find(y);if(rootX!=rootY){parent[rootX]=rootY;}}booleanisConnected(intx,inty){returnfind(x)==find(y);}}publicintmapJump(int[][]arr){if(arr==null||arr.length==0||arr[0].length==0){return0;}intn=arr.length;intm=arr[0].length;// 收集所有可能的边(相邻格子)List<int[]>edges=newArrayList<>();int[]dx={0,1};// 只需要向右和向下,避免重复int[]dy={1,0};for(inti=0;i<n;i++){for(intj=0;j<m;j++){for(intd=0;d<2;d++){intni=i+dx[d];intnj=j+dy[d];if(ni<n&&nj<m){intdiff=Math.abs(arr[ni][nj]-arr[i][j]);edges.add(newint[]{i*m+j,ni*m+nj,diff});}}}}// 按高度差排序edges.sort((a,b)->a[2]-b[2]);UnionFinduf=newUnionFind(n*m);intstart=0;intend=n*m-1;// 从小到大尝试连接for(int[]edge:edges){uf.union(edge[0],edge[1]);if(uf.isConnected(start,end)){returnedge[2];}}return0;}}

算法分析

时间复杂度

  • 解法一/二:O(log(maxH) × N × M)
    • 二分查找:O(log(maxH))
    • 每次验证:O(N × M)
  • 解法三:O(N × M × log(N × M))
    • 排序边:O(N × M × log(N × M))

空间复杂度

  • 所有解法:O(N × M) 用于 visited 数组或并查集

测试用例

publicstaticvoidmain(String[]args){Solutionsolution=newSolution();// 测试用例1int[][]arr1={{1,2},{3,4}};System.out.println(solution.mapJump(arr1));// 输出: 1// 测试用例2int[][]arr2={{1,5,3},{2,7,4},{6,8,9}};System.out.println(solution.mapJump(arr2));// 输出: 2// 测试用例3 - 所有格子高度相同int[][]arr3={{1,1},{1,1}};System.out.println(solution.mapJump(arr3));// 输出: 0}

推荐解法

解法一(二分 + BFS)是最推荐的做法:

  • 思路清晰,易于理解
  • BFS 比 DFS 更安全,不会栈溢出
  • 时间复杂度最优
  • 实现相对简单

这个问题的关键是认识到它是最小化最大高度差的问题,可以用二分答案 + 图遍历来解决。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 16:38:56

等保测评命令——Oracle Linux

依据 GB/T 22239-2019《信息安全技术 网络安全等级保护基本要求》等保2.0三级 标准&#xff0c;针对 Oracle Linux 操作系统及 Oracle数据库 给出可直接落地的测评命令清单。覆盖身份鉴别、访问控制、安全审计、入侵防范、恶意代码防范等核心控制点&#xff0c;已在 Oracle Lin…

作者头像 李华
网站建设 2026/7/14 16:38:59

ResNet网络学习

从VGGNet后&#xff0c;CNN结构就从“卷积层&#xff0b;池化层”范式进化为了“卷积块&#xff0b;池化层”范式。 卷积块就是由1层或多层卷积层组成。 这个概念现在基本成为共识。注意&#xff0c;VGGNet提出后&#xff0c;后面网络对卷积层进行了各种“折腾”、“整活”和“…

作者头像 李华
网站建设 2026/7/14 16:38:58

TensorFlow学习笔记:猫狗识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、基础设置与导入数据 import matplotlib.pyplot as plt import numpy as np import os import PIL import tensorflow as tf from tensorflow import ker…

作者头像 李华
网站建设 2026/7/14 16:39:00

稀土抑烟剂: 让PVC燃烧“静默”的秘密

你或许不曾留意&#xff0c;生活中处处可见的PVC材料&#xff0c;正悄然完成一场安全升级。从建筑工地的防护膜、农业温室大棚&#xff0c;到电子产品包装&#xff0c;这种轻便耐用的塑料无处不在。但鲜为人知的是&#xff0c;传统PVC有一个致命短板——遇火即燃&#xff0c;且…

作者头像 李华
网站建设 2026/7/14 16:39:09

从零开始学网络安全:指纹识别的5种实用方法及工具推荐

从零到一&#xff1a;网络安全中的指纹识别实战指南 刚接触网络安全&#xff0c;你可能听过“指纹识别”这个词&#xff0c;但总觉得它有点神秘&#xff0c;像是电影里特工用的技术。其实&#xff0c;在数字世界里&#xff0c;指纹识别是安全工程师和渗透测试人员最基础、最核心…

作者头像 李华
网站建设 2026/7/14 16:39:10

小白也能玩转CVPR模型:MogFace人脸检测工具部署实录

小白也能玩转CVPR模型&#xff1a;MogFace人脸检测工具部署实录 1. 引言 你有没有想过&#xff0c;自己也能轻松用上那些在顶级学术会议上发表的最新AI模型&#xff1f;今天&#xff0c;我要带你体验的&#xff0c;就是一个来自CVPR 2022的“明星”模型——MogFace&#xff0…

作者头像 李华