给定一个大小为N*M的二维数组,其中, .任务是找到+形模式可实现的最大值。数组的元素可以是负数。
plus(+)形状图案是以坐标为(x, y) 的任意元素为中心,然后将其向所有四个方向扩展(如果可能)而形成的。
plus(+)形状至少有五个元素,分别是{ (x-1, y), (x, y-1), (x, y), (x+1, y), (x, y+1)即}臂应有长度> 1,但不一定需要具有相同的长度。
例子:
Input: N = 3, M = 4
1 1 1 1
-6 1 1 -4
1 1 1 1
Output: 0
Here, (x, y)=(2, 3) center of pattern(+).
Other four arms are, left arm = (2, 2), right arm = (2, 4),
up arm = (1, 3), down arm = (2, 3).
Hence sum of all elements are ( 1 + 1 + (-4) + 1 + 1 ) = 0.
Input: N = 5, M = 3
1 2 3
-6 1 -4
1 1 1
7 8 9
6 3 2
Output: 31
方法:这个问题是标准的Largest Sum Contiguous Subarray 的一个应用。
我们快速预先计算每行和每列的最大连续子序列(子数组)和,在 4 个方向上,即Up、Down、Left 和 Right 。这可以使用一维数组的标准最大连续子序列和来完成。
我们为每个方向制作了四个二维数组的 1。
- up[i][j] – 向上方向的元素的最大和连续子序列,从第 1, 2, 3, …, i 行更正式地说,它表示通过添加元素的连续子序列获得的最大和arr[1][j], arr[2][j], …, arr[i][j] 的列表
- down[i][j] – 向下方向元素的最大和连续子序列,从第 i, i+1, i+2,,…, N 行开始,更正式地说,它表示添加一个连续子获得的最大和- arr[i][j], arr[i+1][j], …, arr[N][j] 列表中元素的序列
- left[i][j] – 左方向元素的最大和连续子序列,来自第 1、2、3、…、j 列。更正式地说,它表示通过添加来自元素的连续子序列获得的最大和arr[i][1], arr[i][2], …, arr[i][j] 的列表
- right[i][j] – 右方向元素的最大和连续子序列,来自列 j, j+1, j+2, …, M 更正式地说,它表示通过添加一个连续子获得的最大和arr[i][j], arr[i][j+1], …, arr[i][M] 列表中的元素序列
剩下的就是检查每个单元格作为+的可能中心,并使用预先计算的数据在 O(1) 中找到+形状实现的值。
下面是上述方法的实现:
C++
// C++ program to find the maximum value
// of a + shaped pattern in 2-D array
#include
using namespace std;
#define N 100
const int n = 3, m = 4;
// Function to return maximum Plus value
int maxPlus(int (&arr)[n][m])
{
// Initializing answer with the minimum value
int ans = INT_MIN;
// Initializing all four arrays
int left[N][N], right[N][N], up[N][N], down[N][N];
// Initializing left and up array.
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
left[i][j] = max(0LL, (j ? left[i][j - 1] : 0LL))
+ arr[i][j];
up[i][j] = max(0LL, (i ? up[i - 1][j] : 0LL))
+ arr[i][j];
}
}
// Initializing right and down array.
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
right[i][j] = max(0LL, (j + 1 == m ? 0LL: right[i][j + 1]))
+ arr[i][j];
down[i][j] = max(0LL, (i + 1 == n ? 0LL: down[i + 1][j]))
+ arr[i][j];
}
}
// calculating value of maximum Plus (+) sign
for (int i = 1; i < n - 1; ++i)
for (int j = 1; j < m - 1; ++j)
ans = max(ans, up[i - 1][j] + down[i + 1][j]
+ left[i][j - 1] + right[i][j + 1] + arr[i][j]);
return ans;
}
// Driver code
int main()
{
int arr[n][m] = { { 1, 1, 1, 1 },
{ -6, 1, 1, -4 },
{ 1, 1, 1, 1 } };
// Function call to find maximum value
cout << maxPlus(arr);
return 0;
}
Java
// Java program to find the maximum value
// of a + shaped pattern in 2-D array
class GFG
{
public static int N = 100;
public static int n = 3, m = 4;
// Function to return maximum Plus value
public static int maxPlus(int[][] arr)
{
// Initializing answer with the minimum value
int ans = Integer.MIN_VALUE;
// Initializing all four arrays
int[][] left = new int[N][N];
int[][] right = new int[N][N];
int[][] up = new int[N][N];
int[][] down = new int[N][N];
// Initializing left and up array.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
left[i][j] = Math.max(0, ((j != 0) ? left[i][j - 1] : 0))
+ arr[i][j];
up[i][j] = Math.max(0, ((i != 0)? up[i - 1][j] : 0))
+ arr[i][j];
}
}
// Initializing right and down array.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
right[i][j] = Math.max(0, (j + 1 == m ? 0: right[i][j + 1]))
+ arr[i][j];
down[i][j] = Math.max(0, (i + 1 == n ? 0: down[i + 1][j]))
+ arr[i][j];
}
}
// calculating value of maximum Plus (+) sign
for (int i = 1; i < n - 1; ++i)
for (int j = 1; j < m - 1; ++j)
ans = Math.max(ans, up[i - 1][j] + down[i + 1][j]
+ left[i][j - 1] + right[i][j + 1] + arr[i][j]);
return ans;
}
// Driver code
public static void main(String[] args) {
int[][] arr = new int[][]{ { 1, 1, 1, 1 },
{ -6, 1, 1, -4 },
{ 1, 1, 1, 1 } };
// Function call to find maximum value
System.out.println( maxPlus(arr) );
}
}
// This code is contributed by PrinciRaj1992.
Python 3
# Python 3 program to find the maximum value
# of a + shaped pattern in 2-D array
N = 100
n = 3
m = 4
# Function to return maximum
# Plus value
def maxPlus(arr):
# Initializing answer with
# the minimum value
ans = 0
# Initializing all four arrays
left = [[0 for x in range(N)]
for y in range(N)]
right = [[0 for x in range(N)]
for y in range(N)]
up = [[0 for x in range(N)]
for y in range(N)]
down = [[0 for x in range(N)]
for y in range(N)]
# Initializing left and up array.
for i in range(n) :
for j in range(m) :
left[i][j] = (max(0, (left[i][j - 1] if j else 0)) +
arr[i][j])
up[i][j] = (max(0, (up[i - 1][j] if i else 0)) +
arr[i][j])
# Initializing right and down array.
for i in range(n) :
for j in range(m) :
right[i][j] = max(0, (0 if (j + 1 == m ) else
right[i][j + 1])) + arr[i][j]
down[i][j] = max(0, (0 if (i + 1 == n ) else
down[i + 1][j])) + arr[i][j]
# calculating value of maximum
# Plus (+) sign
for i in range(1, n - 1):
for j in range(1, m - 1):
ans = max(ans, up[i - 1][j] + down[i + 1][j] +
left[i][j - 1] + right[i][j + 1] +
arr[i][j])
return ans
# Driver code
if __name__ == "__main__":
arr = [[ 1, 1, 1, 1 ],
[ -6, 1, 1, -4 ],
[ 1, 1, 1, 1 ]]
# Function call to find maximum value
print(maxPlus(arr))
# This code is contributed
# by ChitraNayal
C#
// C# program to find the maximum value
// of a + shaped pattern in 2-D array
using System;
class GFG
{
public static int N = 100;
public static int n = 3, m = 4;
// Function to return maximum Plus value
public static int maxPlus(int[,] arr)
{
// Initializing answer with the minimum value
int ans = int.MinValue;
// Initializing all four arrays
int[,] left = new int[N,N];
int[,] right = new int[N,N];
int[,] up = new int[N,N];
int[,] down = new int[N,N];
// Initializing left and up array.
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
left[i,j] = Math.Max(0, ((j != 0) ? left[i,j - 1] : 0))
+ arr[i,j];
up[i,j] = Math.Max(0, ((i != 0)? up[i - 1,j] : 0))
+ arr[i,j];
}
}
// Initializing right and down array.
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
right[i,j] = Math.Max(0, (j + 1 == m ? 0: right[i,j + 1]))
+ arr[i,j];
down[i,j] = Math.Max(0, (i + 1 == n ? 0: down[i + 1,j]))
+ arr[i,j];
}
}
// calculating value of maximum Plus (+) sign
for (int i = 1; i < n - 1; ++i)
for (int j = 1; j < m - 1; ++j)
ans = Math.Max(ans, up[i - 1,j] + down[i + 1,j]
+ left[i,j - 1] + right[i,j + 1] + arr[i,j]);
return ans;
}
// Driver code
static void Main()
{
int[,] arr = new int[,]{ { 1, 1, 1, 1 },
{ -6, 1, 1, -4 },
{ 1, 1, 1, 1 } };
// Function call to find maximum value
Console.Write( maxPlus(arr) );
}
}
// This code is contributed by DrRoot_
Javascript
输出:
0
时间复杂度: O(N 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。