给定一个包含整数值的矩阵,其中矩阵的每个单元格代表建筑物的高度。找到从第一个建筑物 (0, 0) 到最后一个 (n-1, m-1) 所需的最小跳跃。从一个单元格跳到下一个单元格是两个建筑物高度之间的绝对差异。
例子 :
Input : int height[][] = {{ 5, 4, 2 },
{ 9, 2, 1 },
{ 2, 5, 9 },
{ 1, 3, 11}};
Output : 12
The minimum jump path is 5 -> 2 -> 5
-> 11. Total jumps is 3 + 3 + 6 = 12.
朴素的递归解决方案:
上面的问题可以通过使用递归轻松解决。到达 (m, n) 的路径必须通过 3 个单元格之一:(m-1, n-1) 或 (m-1, n) 或 (m, n-1)。因此,达到 (m, n) 的最小跳跃可以写成“3 个单元格的最小跳跃加上当前跳跃。
下面是该方法的实现。
C++
// Recursive CPP program to find minimum jumps
// to reach last building from first.
#include
using namespace std;
# define R 4
# define C 3
bool isSafe(int x, int y)
{
return (x < R && y < C);
}
/* Returns minimum jump path from (0, 0) to
(m, n) in hight[R][C]*/
int minJump(int height[R][C], int x, int y)
{
// base case
if (x == R - 1 && y == C - 1)
return 0;
// Find minimum jumps if we go through diagonal
int diag = INT_MAX;
if (isSafe(x + 1, y + 1))
diag = minJump(height, x + 1, y + 1) +
abs(height[x][y] - height[x + 1][y + 1]);
// Find minimum jumps if we go through down
int down = INT_MAX;
if (isSafe(x + 1, y))
down = minJump(height, x + 1, y) +
abs(height[x][y] - height[x + 1][y]);
// Find minimum jumps if we go through right
int right = INT_MAX;
if (isSafe(x, y + 1))
right = minJump(height, x, y + 1) +
abs(height[x][y] - height[x][y + 1]);
// return minimum jumps
return min({down, right, diag});
}
/* Driver program to test above functions */
int main()
{
int height[][C] = { { 5, 4, 2 },
{ 9, 2, 1 },
{ 2, 5, 9 },
{ 1, 3, 11 } };
cout << minJump(height, 0, 0);
return 0;
}
Java
// Recursive Java program
// to find minimum jumps
// to reach last building
// from first.
class GFG {
static boolean isSafe(int x, int y)
{
return (x < 4 && y < 3);
}
// Returns minimum jump
// path from (0, 0) to
// (m, n) in hight[R][C]
static int minJump(int height[][], int x,
int y)
{
// base case
if (x == 4 - 1 && y == 3 - 1)
return 0;
// Find minimum jumps
// if we go through
// diagonal
int diag = Integer.MAX_VALUE;
if (isSafe(x + 1, y + 1))
diag = minJump(height, x + 1, y + 1) +
Math.abs(height[x][y] - height[x + 1][y + 1]);
// Find minimum jumps
// if we go through
// down
int down = Integer.MAX_VALUE;
if (isSafe(x + 1, y))
down = minJump(height, x + 1, y) +
Math.abs(height[x][y] - height[x + 1][y]);
// Find minimum jumps
// if we go through right
int right = Integer.MAX_VALUE;
if (isSafe(x, y + 1))
right = minJump(height, x, y + 1) +
Math.abs(height[x][y] - height[x][y + 1]);
// return minimum jumps
return Math.min(down, Math.min(right, diag));
}
// Driver program
public static void main(String[] args)
{
int height[][] = { { 5, 4, 2 },
{ 9, 2, 1 },
{ 2, 5, 9 },
{ 1, 3, 11} };
System.out.println(minJump(height, 0, 0));
}
}
// This article is contributed by Prerna Saini.
Python3
# Recursive Python3 program to find minimum jumps
# to reach last building from first.
R = 4
C = 3
def isSafe(x, y):
return (x < R and y < C)
# Returns minimum jump path from
# (0, 0) to (m, n) in hight[R][C]
def minJump(height, x, y):
# base case
if (x == R - 1 and y == C - 1):
return 0
# Find minimum jumps if we go
# through diagonal
diag = 10**9
if (isSafe(x + 1, y + 1)):
diag = (minJump(height, x + 1, y + 1) +
abs(height[x][y] -
height[x + 1][y + 1]))
# Find minimum jumps if we go through down
down = 10**9
if (isSafe(x + 1, y)):
down = (minJump(height, x + 1, y) +
abs(height[x][y] -
height[x + 1][y]))
# Find minimum jumps if we go through right
right = 10**9
if (isSafe(x, y + 1)):
right = (minJump(height, x, y + 1) +
abs(height[x][y] -
height[x][y + 1]))
# return minimum jumps
return min([down, right, diag])
# Driver Code
height = [ [ 5, 4, 2 ],
[ 9, 2, 1 ],
[ 2, 5, 9 ],
[ 1, 3, 11 ] ]
print(minJump(height, 0, 0))
# This code is contributed by mohit kumar
C#
// Recursive C# program
// to find minimum jumps
// to reach last building
// from first.
using System;
class GFG {
static bool isSafe(int x, int y)
{
return (x < 4 && y < 3);
}
// Returns minimum jump
// path from (0, 0) to
// (m, n) in hight[R][C]
static int minJump(int [,]height,
int x, int y)
{
// base case
if (x == 4 - 1 && y == 3 - 1)
return 0;
// Find minimum jumps
// if we go through
// diagonal
int diag = int.MaxValue;
if (isSafe(x + 1, y + 1))
diag = minJump(height, x + 1, y + 1) +
Math.Abs(height[x,y] -
height[x + 1,y + 1]);
// Find minimum jumps
// if we go through
// down
int down = int.MaxValue;
if (isSafe(x + 1, y))
down = minJump(height, x + 1, y) +
Math.Abs(height[x,y] -
height[x + 1,y]);
// Find minimum jumps
// if we go through right
int right = int.MaxValue;
if (isSafe(x, y + 1))
right = minJump(height, x, y + 1) +
Math.Abs(height[x,y] -
height[x,y + 1]);
// return minimum jumps
return Math.Min(down, Math.Min(right, diag));
}
// Driver code
public static void Main()
{
int [,]height = {{5, 4, 2},
{9, 2, 1},
{2, 5, 9},
{1, 3, 11}};
Console.Write(minJump(height, 0, 0));
}
}
// This code is contributed by nitin mittal
PHP
Javascript
C++
// A Dynamic Programming based CPP program to find
// minimum jumps to reach last building from first.
#include
using namespace std;
#define R 4
#define C 3
bool isSafe(int x, int y)
{
return (x < R && y < C);
}
// Lookup table used for memoization.
int dp[R][C];
/* Returns minimum jump path from (0, 0) to (m, n)
in hight[R][C]*/
int minJump(int height[R][C], int x, int y)
{
// if we visited it before
if (dp[x][y] != -1)
return dp[x][y];
if (x == R - 1 && y == C - 1)
return (dp[x][y] = 0);
// Find minimum jumps if we go through diagonal
int diag = INT_MAX;
if (isSafe(x + 1, y + 1))
diag = minJump(height, x + 1, y + 1) +
abs(height[x][y] - height[x + 1][y + 1]);
// Find minimum jumps if we go through down
int down = INT_MAX;
if (isSafe(x + 1, y))
down = minJump(height, x + 1, y) +
abs(height[x][y] - height[x + 1][y]);
// Find minimum jumps if we go through right
int right = INT_MAX;
if (isSafe(x, y + 1))
right = minJump(height, x, y + 1) +
abs(height[x][y] - height[x][y + 1]);
// return minimum jump
dp[x][y] = min({down, right, diag});
return dp[x][y];
}
/* Driver program to test above functions */
int main()
{
int height[][C] = { { 5, 4, 2 },
{ 9, 2, 1 },
{ 2, 5, 9 },
{ 1, 3, 11 } };
memset(dp, -1, sizeof(dp));
cout << minJump(height, 0, 0);
return 0;
}
Java
// A Dynamic Programming based Java program to find
// minimum jumps to reach last building from first.
import java.util.*;
class GFG
{
static int R = 4;
static int C = 3;
static boolean isSafe(int x, int y)
{
return (x < R && y < C);
}
// Lookup table used for memoization.
static int[][] dp = new int[R][C];
/* Returns minimum jump path from (0, 0) to (m, n)
in hight[R][C]*/
static int minJump(int height[][], int x, int y)
{
// if we visited it before
if (dp[x][y] != -1)
{
return dp[x][y];
}
if (x == R - 1 && y == C - 1)
{
return (dp[x][y] = 0);
}
// Find minimum jumps if we go through diagonal
int diag = Integer.MAX_VALUE;
if (isSafe(x + 1, y + 1))
{
diag = minJump(height, x + 1, y + 1)
+ Math.abs(height[x][y] - height[x + 1][y + 1]);
}
// Find minimum jumps if we go through down
int down = Integer.MAX_VALUE;
if (isSafe(x + 1, y))
{
down = minJump(height, x + 1, y)
+ Math.abs(height[x][y] - height[x + 1][y]);
}
// Find minimum jumps if we go through right
int right = Integer.MAX_VALUE;
if (isSafe(x, y + 1))
{
right = minJump(height, x, y + 1)
+ Math.abs(height[x][y] - height[x][y + 1]);
}
// return minimum jump
dp[x][y] = Math.min(Math.min(down, right), diag);
return dp[x][y];
}
/* Driver program to test above functions */
public static void main(String[] args)
{
int height[][] = {{5, 4, 2},
{9, 2, 1},
{2, 5, 9},
{1, 3, 11}};
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
dp[i][j] = -1;
}
}
System.out.println(minJump(height, 0, 0));
}
}
/* This code is contributed by PrinciRaj1992 */
Python
# A Dynamic Programming based Python program to find
# minimum jumps to reach last building from first.
R = 4
C = 3
def isSafe( x, y):
return (x < R and y < C)
# Lookup table used for memoization.
dp = [[-1 for i in range(C)] for i in range(R)]
# Returns minimum jump path from (0, 0) to (m, n)
# in hight[R][C]*/
def minJump(height, x, y):
# if we visited it before
if (dp[x][y] != -1):
return dp[x][y]
if (x == R - 1 and y == C - 1):
return (dp[x][y] == 0)
# Find minimum jumps if we go through diagonal
diag = 10**9
if (isSafe(x + 1, y + 1)):
diag = minJump(height, x + 1, y + 1) + abs(height[x][y] - height[x + 1][y + 1])
# Find minimum jumps if we go through down
down =10**9
if (isSafe(x + 1, y)):
down = minJump(height, x + 1, y) + abs(height[x][y] - height[x + 1][y])
# Find minimum jumps if we go through right
right =10**9
if (isSafe(x, y + 1)):
right = minJump(height, x, y + 1) + abs(height[x][y] - height[x][y + 1])
# return minimum jump
dp[x][y] = min(down, right, diag)
return dp[x][y]
# Driver code
height=[[ 5, 4, 2 ],
[ 9, 2, 1 ],
[ 2, 5, 9 ],
[ 1, 3, 11 ]]
print(minJump(height, 0, 0))
# This code is contributed by mohit kumar 29
C#
// A Dynamic Programming based C# program to find
// minimum jumps to reach last building from first.
using System;
class GFG
{
static int R = 4;
static int C = 3;
static Boolean isSafe(int x, int y)
{
return (x < R && y < C);
}
// Lookup table used for memoization.
static int[,] dp = new int[R,C];
/* Returns minimum jump path from (0, 0) to (m, n)
in hight[R,C]*/
static int minJump(int [,]height, int x, int y)
{
// if we visited it before
if (dp[x,y] != -1)
{
return dp[x,y];
}
if (x == R - 1 && y == C - 1)
{
return (dp[x,y] = 0);
}
// Find minimum jumps if we go through diagonal
int diag = int.MaxValue;
if (isSafe(x + 1, y + 1))
{
diag = minJump(height, x + 1, y + 1)
+ Math.Abs(height[x,y] - height[x + 1,y + 1]);
}
// Find minimum jumps if we go through down
int down = int.MaxValue;
if (isSafe(x + 1, y))
{
down = minJump(height, x + 1, y)
+ Math.Abs(height[x,y] - height[x + 1,y]);
}
// Find minimum jumps if we go through right
int right = int.MaxValue;
if (isSafe(x, y + 1))
{
right = minJump(height, x, y + 1)
+ Math.Abs(height[x,y] - height[x,y + 1]);
}
// return minimum jump
dp[x,y] = Math.Min(Math.Min(down, right), diag);
return dp[x,y];
}
/* Driver code */
public static void Main(String[] args)
{
int [,]height = {{5, 4, 2},
{9, 2, 1},
{2, 5, 9},
{1, 3, 11}};
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
dp[i,j] = -1;
}
}
Console.WriteLine(minJump(height, 0, 0));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出 :
12
这个解决方案的时间复杂度是指数级的。
动态规划解决方案:
如果我们绘制上述递归解的递归树,我们可以观察到重叠的子问题。由于问题有重叠的子问题,我们可以使用动态规划有效地解决它。以下是基于动态规划的解决方案。
C++
// A Dynamic Programming based CPP program to find
// minimum jumps to reach last building from first.
#include
using namespace std;
#define R 4
#define C 3
bool isSafe(int x, int y)
{
return (x < R && y < C);
}
// Lookup table used for memoization.
int dp[R][C];
/* Returns minimum jump path from (0, 0) to (m, n)
in hight[R][C]*/
int minJump(int height[R][C], int x, int y)
{
// if we visited it before
if (dp[x][y] != -1)
return dp[x][y];
if (x == R - 1 && y == C - 1)
return (dp[x][y] = 0);
// Find minimum jumps if we go through diagonal
int diag = INT_MAX;
if (isSafe(x + 1, y + 1))
diag = minJump(height, x + 1, y + 1) +
abs(height[x][y] - height[x + 1][y + 1]);
// Find minimum jumps if we go through down
int down = INT_MAX;
if (isSafe(x + 1, y))
down = minJump(height, x + 1, y) +
abs(height[x][y] - height[x + 1][y]);
// Find minimum jumps if we go through right
int right = INT_MAX;
if (isSafe(x, y + 1))
right = minJump(height, x, y + 1) +
abs(height[x][y] - height[x][y + 1]);
// return minimum jump
dp[x][y] = min({down, right, diag});
return dp[x][y];
}
/* Driver program to test above functions */
int main()
{
int height[][C] = { { 5, 4, 2 },
{ 9, 2, 1 },
{ 2, 5, 9 },
{ 1, 3, 11 } };
memset(dp, -1, sizeof(dp));
cout << minJump(height, 0, 0);
return 0;
}
Java
// A Dynamic Programming based Java program to find
// minimum jumps to reach last building from first.
import java.util.*;
class GFG
{
static int R = 4;
static int C = 3;
static boolean isSafe(int x, int y)
{
return (x < R && y < C);
}
// Lookup table used for memoization.
static int[][] dp = new int[R][C];
/* Returns minimum jump path from (0, 0) to (m, n)
in hight[R][C]*/
static int minJump(int height[][], int x, int y)
{
// if we visited it before
if (dp[x][y] != -1)
{
return dp[x][y];
}
if (x == R - 1 && y == C - 1)
{
return (dp[x][y] = 0);
}
// Find minimum jumps if we go through diagonal
int diag = Integer.MAX_VALUE;
if (isSafe(x + 1, y + 1))
{
diag = minJump(height, x + 1, y + 1)
+ Math.abs(height[x][y] - height[x + 1][y + 1]);
}
// Find minimum jumps if we go through down
int down = Integer.MAX_VALUE;
if (isSafe(x + 1, y))
{
down = minJump(height, x + 1, y)
+ Math.abs(height[x][y] - height[x + 1][y]);
}
// Find minimum jumps if we go through right
int right = Integer.MAX_VALUE;
if (isSafe(x, y + 1))
{
right = minJump(height, x, y + 1)
+ Math.abs(height[x][y] - height[x][y + 1]);
}
// return minimum jump
dp[x][y] = Math.min(Math.min(down, right), diag);
return dp[x][y];
}
/* Driver program to test above functions */
public static void main(String[] args)
{
int height[][] = {{5, 4, 2},
{9, 2, 1},
{2, 5, 9},
{1, 3, 11}};
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
dp[i][j] = -1;
}
}
System.out.println(minJump(height, 0, 0));
}
}
/* This code is contributed by PrinciRaj1992 */
Python
# A Dynamic Programming based Python program to find
# minimum jumps to reach last building from first.
R = 4
C = 3
def isSafe( x, y):
return (x < R and y < C)
# Lookup table used for memoization.
dp = [[-1 for i in range(C)] for i in range(R)]
# Returns minimum jump path from (0, 0) to (m, n)
# in hight[R][C]*/
def minJump(height, x, y):
# if we visited it before
if (dp[x][y] != -1):
return dp[x][y]
if (x == R - 1 and y == C - 1):
return (dp[x][y] == 0)
# Find minimum jumps if we go through diagonal
diag = 10**9
if (isSafe(x + 1, y + 1)):
diag = minJump(height, x + 1, y + 1) + abs(height[x][y] - height[x + 1][y + 1])
# Find minimum jumps if we go through down
down =10**9
if (isSafe(x + 1, y)):
down = minJump(height, x + 1, y) + abs(height[x][y] - height[x + 1][y])
# Find minimum jumps if we go through right
right =10**9
if (isSafe(x, y + 1)):
right = minJump(height, x, y + 1) + abs(height[x][y] - height[x][y + 1])
# return minimum jump
dp[x][y] = min(down, right, diag)
return dp[x][y]
# Driver code
height=[[ 5, 4, 2 ],
[ 9, 2, 1 ],
[ 2, 5, 9 ],
[ 1, 3, 11 ]]
print(minJump(height, 0, 0))
# This code is contributed by mohit kumar 29
C#
// A Dynamic Programming based C# program to find
// minimum jumps to reach last building from first.
using System;
class GFG
{
static int R = 4;
static int C = 3;
static Boolean isSafe(int x, int y)
{
return (x < R && y < C);
}
// Lookup table used for memoization.
static int[,] dp = new int[R,C];
/* Returns minimum jump path from (0, 0) to (m, n)
in hight[R,C]*/
static int minJump(int [,]height, int x, int y)
{
// if we visited it before
if (dp[x,y] != -1)
{
return dp[x,y];
}
if (x == R - 1 && y == C - 1)
{
return (dp[x,y] = 0);
}
// Find minimum jumps if we go through diagonal
int diag = int.MaxValue;
if (isSafe(x + 1, y + 1))
{
diag = minJump(height, x + 1, y + 1)
+ Math.Abs(height[x,y] - height[x + 1,y + 1]);
}
// Find minimum jumps if we go through down
int down = int.MaxValue;
if (isSafe(x + 1, y))
{
down = minJump(height, x + 1, y)
+ Math.Abs(height[x,y] - height[x + 1,y]);
}
// Find minimum jumps if we go through right
int right = int.MaxValue;
if (isSafe(x, y + 1))
{
right = minJump(height, x, y + 1)
+ Math.Abs(height[x,y] - height[x,y + 1]);
}
// return minimum jump
dp[x,y] = Math.Min(Math.Min(down, right), diag);
return dp[x,y];
}
/* Driver code */
public static void Main(String[] args)
{
int [,]height = {{5, 4, 2},
{9, 2, 1},
{2, 5, 9},
{1, 3, 11}};
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
dp[i,j] = -1;
}
}
Console.WriteLine(minJump(height, 0, 0));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
12
时间复杂度: (R*C)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。