Given a matrix A[][] of size N * N, where each matrix element is either -1 or 1. One can move from (X, Y) to either (X + 1, Y) or (X, Y + 1) but not out of the matrix. The task is to check whether a path exists from the top-left to the bottom-right corner such that the sum of all elements in the path is X.
Examples:
Input: arr[][] = {{1, 1, 1, 1}, {-1, 1, -1, -1}, {-1, 1, -1, 1}, {-1, -1, 1, 1}}, X = 3
Output: Yes
Explanation:
One path will be :
Cell 1: (0, 0), Sum = 1 now moving down to (1, 0)
Cell 2: (1, 0), Sum = 1 – 1 now moving right to (1, 1)
Cell 3: (1, 1), Sum = 1 – 1 + 1 now moving down to (2, 1)
Cell 4: (2, 1), Sum = 1 – 1 + 1 + 1 now moving down to (3, 1)
Cell 5: (3, 1), Sum = 1 – 1 + 1 + 1 – 1 now moving right to (3, 2)
Cell 6: (3, 2), Sum = 1 – 1 + 1 + 1 – 1 + 1 now moving right to (3, 3)
Cell 7: (3, 3), Sum = 1 – 1 + 1 + 1 – 1 + 1 + 1
The total sum is 3 which is equal to X Hence Print “Yes”. For a detailed explanation check the Efficient approach.Input: arr[][] = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, X = 4
Output: No
Naive approach: The basic way to solve the problem is as follows:
Visit all paths and track their sum by using recursive brute force in exponential time.
Time Complexity: O(2N * N)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following idea
Let’s say minPathSum and maxPathSum are the maximum and minimum path sum from (0, 0) to (N-1, N-1) which can be calculated by Dynamic programming.
- dp[i][j] is minimum/maximum path sum at cell (i, j)
- recurrence relation : dp[i][j] = min or max of (dp[i – 1][j], dp[i][j – 1]) + A[i][j]
In this problem most important thing is greedy observation below.
- if number of cells from top-left to bottom-right is odd then all path sums of odd values can be generated in range [minPathSum, maxPathSum]
- if number of cells from top-left to bottom-right are even then all path sum of even values can be generated in range [minPathSum, maxPathSum]
Follow the steps below to solve the problem:
- Calculating minPathSum and maxPathSum using dynamic programming.
- Calculating the number of cells from (1, 1) to (N, N) with the formula numberOfCells = 2 * N – 1.
- if X has the same parity(fact of being odd or even) as numberOfCells and X is in between range [minPathSum, maxPathSum] print “Yes” else print “No”.
Below is the implementation of the above approach:
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to check whether paths // exists from (1, 1) to (N, N) such // that its sum is X void isReachable(vector<vector< int > > A, int N, int X)
{ // DP table for finding maximum and
// minimum path sum
vector<vector<vector< int > > > dp(
N, vector<vector< int > >(N, vector< int >(2, 0)));
// Base Case
dp[0][0][0] = A[0][0];
dp[0][0][1] = A[0][0];
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < N; j++) {
// Base Case
if (i == 0 and j == 0)
continue ;
// When coming from left is not
// possible
if (i == 0) {
dp[i][j][0] = dp[i][j - 1][0] + A[i][j - 1];
dp[i][j][1] = dp[i][j - 1][1] + A[i][j - 1];
}
// When coming from Left is not
// possible
else if (j == 0) {
dp[i][j][0] = dp[i - 1][j][0] + A[i - 1][j];
dp[i][j][1] = dp[i - 1][j][1] + A[i - 1][j];
}
// When Both coming from Left and Up
// possible
else {
dp[i][j][0]
= min(dp[i - 1][j][0] + A[i - 1][j],
dp[i][j - 1][0] + A[i][j - 1]);
dp[i][j][1]
= max(dp[i - 1][j][1] + A[i - 1][j],
dp[i][j - 1][1] + A[i][j - 1]);
}
}
}
// Minimum Path sum from (1, 1) to (N, N)
int minimumPathSum = dp[N - 1][N - 1][0];
// Maximum Path sum from (1, 1) to (N, N)
int maximumPathSum = dp[N - 1][N - 1][1];
// Number of cells in path from (1, 1) to (N, N)
int numberOfCells = 2 * N - 1;
// Parity of both numberOfCells from (1, 1)
// to (N, N) and X should be same and X
// should be in between range from
// minmumPathSum and maximumPathSum
if (numberOfCells % 2 == X % 2 && minimumPathSum <= X
&& maximumPathSum >= X)
cout << "Yes" << endl;
else
cout << "No" << endl;
} // Driver Code int main()
{ // Input 1
vector<vector< int > > A{ { 1, 1, 1, 1 },
{ -1, 1, -1, -1 },
{ -1, 1, -1, 1 },
{ -1, -1, 1, 1 } };
int N = A.size();
int X = 3;
// Function Call
isReachable(A, N, X);
// Input 2
vector<vector< int > > A1{ { 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 } };
int N1 = A1.size();
int X1 = 4;
// Function Call
isReachable(A1, N1, X1);
return 0;
} |
// Java code to implement the approach class GFG {
// Function to check whether paths exists from (1, 1) to
// (N, N) such that its sum is X
public static void isReachable( int [][] A, int N, int X) {
// DP table for finding maximum and minimum path sum
int [][][] dp = new int [N][N][ 2 ];
// Base Case
dp[ 0 ][ 0 ][ 0 ] = A[ 0 ][ 0 ];
dp[ 0 ][ 0 ][ 1 ] = A[ 0 ][ 0 ];
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < N; j++) {
// Base Case
if (i == 0 && j == 0 ) {
continue ;
}
// When coming from left is not possible
if (i == 0 ) {
dp[i][j][ 0 ] = dp[i][j - 1 ][ 0 ] + A[i][j - 1 ];
dp[i][j][ 1 ] = dp[i][j - 1 ][ 1 ] + A[i][j - 1 ];
}
// When coming from Left is not possible
else if (j == 0 ) {
dp[i][j][ 0 ] = dp[i - 1 ][j][ 0 ] + A[i - 1 ][j];
dp[i][j][ 1 ] = dp[i - 1 ][j][ 1 ] + A[i - 1 ][j];
}
// When Both coming from Left and Up possible
else {
dp[i][j][ 0 ]
= Math.min(dp[i - 1 ][j][ 0 ] + A[i - 1 ][j],
dp[i][j - 1 ][ 0 ] + A[i][j - 1 ]);
dp[i][j][ 1 ]
= Math.max(dp[i - 1 ][j][ 1 ] + A[i - 1 ][j],
dp[i][j - 1 ][ 1 ] + A[i][j - 1 ]);
}
}
}
// Minimum Path sum from (1, 1) to (N, N)
int minimumPathSum = dp[N - 1 ][N - 1 ][ 0 ];
// Maximum Path sum from (1, 1) to (N, N)
int maximumPathSum = dp[N - 1 ][N - 1 ][ 1 ];
// Number of cells in path from (1, 1) to (N, N)
int numberOfCells = 2 * N - 1 ;
// Parity of both numberOfCells from (1, 1)
// to (N, N) and X should be same and X
// should be in between range from
// minmumPathSum and maximumPathSum
if (numberOfCells % 2 == X % 2 && minimumPathSum <= X &&
maximumPathSum >= X) {
System.out.println( "Yes" );
} else {
System.out.println( "No" );
}
}
// Driver Code
public static void main(String[] args) {
int [][] A = { { 1 , 1 , 1 , 1 },
{ - 1 , 1 , - 1 , - 1 },
{ - 1 , 1 , - 1 , 1 },
{ - 1 , - 1 , 1 , 1 }
};
int N = 4 ;
int X = 3 ;
// Function Call
isReachable(A, N, X);
// Input 2
int [][] A1 = { { 1 , 1 , 1 , 1 },
{ - 1 , 1 , - 1 , - 1 },
{ - 1 , 1 , - 1 , 1 },
{ - 1 , - 1 , 1 , 1 }
};
int N1 = 3 ;
int X1 = 4 ;
// Function Call
isReachable(A1, N1, X1);
}
} |
# Python code to implement the approach import math
# Function to check whether paths exists from # (1, 1) to (N, N) such that its sum is x def is_reachable(A, N, X):
# DP table for finding maximum and minimum path sum
dp = [[[ 0 for i in range ( 2 )] for j in range (N)] for k in range (N)]
# Base Case
dp[ 0 ][ 0 ][ 0 ] = A[ 0 ][ 0 ]
dp[ 0 ][ 0 ][ 1 ] = A[ 0 ][ 0 ]
for i in range (N):
for j in range (N):
# Base Case
if i = = 0 and j = = 0 :
continue
# When coming from left is not possible
elif i = = 0 :
dp[i][j][ 0 ] = dp[i][j - 1 ][ 0 ] + A[i][j - 1 ]
dp[i][j][ 1 ] = dp[i][j - 1 ][ 1 ] + A[i][j - 1 ]
# When coming from Left is not possible
elif j = = 0 :
dp[i][j][ 0 ] = dp[i - 1 ][j][ 0 ] + A[i - 1 ][j]
dp[i][j][ 1 ] = dp[i - 1 ][j][ 1 ] + A[i - 1 ][j]
# When Both coming from Left and Up possible
else :
dp[i][j][ 0 ] = min (dp[i - 1 ][j][ 0 ] + A[i - 1 ][j], dp[i][j - 1 ][ 0 ] + A[i][j - 1 ])
dp[i][j][ 1 ] = max (dp[i - 1 ][j][ 1 ] + A[i - 1 ][j], dp[i][j - 1 ][ 1 ] + A[i][j - 1 ])
# Minimum Path sum from (1, 1) to (N, N)
minimum_path_sum = dp[N - 1 ][N - 1 ][ 0 ]
# Maximum Path sum from (1, 1) to (N, N)
maximum_path_sum = dp[N - 1 ][N - 1 ][ 1 ]
# Number of cells in path from (1, 1) to (N, N)
number_of_cells = 2 * N - 1
# Parity of both numberOfCells from (1, 1)
# to (N, N) and X should be same and X
# should be in between range from
# minmumPathSum and maximumPathSum
if number_of_cells % 2 = = X % 2 and minimum_path_sum < = X and maximum_path_sum > = X:
print ( "Yes" )
else :
print ( "No" )
# Driver Code A = [[ 1 , 1 , 1 , 1 ], [ - 1 , 1 , - 1 , - 1 ], [ - 1 , 1 , - 1 , 1 ], [ - 1 , - 1 , 1 , 1 ]]
N = 4
X = 3
# Function Call is_reachable(A, N, X) # Input 2 A1 = [[ 1 , 1 , 1 , 1 ], [ - 1 , 1 , - 1 , - 1 ], [ - 1 , 1 , - 1 , 1 ], [ - 1 , - 1 , 1 , 1 ]]
N1 = 3
X1 = 4
# Function Call is_reachable(A1, N1, X1) # This code is contributed by lokeshmvs21. |
// C# code to implement the approach using System;
using System.Collections.Generic;
class GFG {
// Function to check whether paths
// exists from (1, 1) to (N, N) such
// that its sum is X
static void isReachable(List<List< int > > A, int N, int X)
{
// DP table for finding maximum and
// minimum path sum
int [,,]dp= new int [N,N,2];
for ( int i=0; i<N; i++)
{
for ( int j=0; j<N; j++)
{
for ( int k=0; k<2; k++)
dp[i,j,k]=0;
}
}
// Base Case
dp[0,0,0] = A[0][0];
dp[0,0,1] = A[0][0];
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < N; j++) {
// Base Case
if (i == 0 && j == 0)
continue ;
// When coming from left is not
// possible
if (i == 0) {
dp[i,j,0] = dp[i,j - 1,0] + A[i][j - 1];
dp[i,j,1] = dp[i,j - 1,1] + A[i][j - 1];
}
// When coming from Left is not
// possible
else if (j == 0) {
dp[i,j,0] = dp[i - 1,j,0] + A[i - 1][j];
dp[i,j,1] = dp[i - 1,j,1] + A[i - 1][j];
}
// When Both coming from Left and Up
// possible
else {
dp[i,j,0]
= Math.Min(dp[i - 1,j,0] + A[i - 1][j],
dp[i,j - 1,0] + A[i][j - 1]);
dp[i,j,1]
= Math.Max(dp[i - 1,j,1] + A[i - 1][j],
dp[i,j - 1,1] + A[i][j - 1]);
}
}
}
// Minimum Path sum from (1, 1) to (N, N)
int minimumPathSum = dp[N - 1,N - 1,0];
// Maximum Path sum from (1, 1) to (N, N)
int maximumPathSum = dp[N - 1,N - 1,1];
// Number of cells in path from (1, 1) to (N, N)
int numberOfCells = 2 * N - 1;
// Parity of both numberOfCells from (1, 1)
// to (N, N) and X should be same and X
// should be in between range from
// minmumPathSum and maximumPathSum
if (numberOfCells % 2 == X % 2 && minimumPathSum <= X
&& maximumPathSum >= X)
Console.Write( "Yes\n" );
else
Console.Write( "No\n" );
}
// Driver Code
public static void Main()
{
// Input 1
List<List< int > > A= new List<List< int >>();
A.Add( new List< int >{ 1, 1, 1, 1 });
A.Add( new List< int >{ -1, 1, -1, -1 });
A.Add( new List< int >{ -1, 1, -1, 1 });
A.Add( new List< int >{ -1, -1, 1, 1 });
int N = A.Count;
int X = 3;
// Function Call
isReachable(A, N, X);
// Input 2
List<List< int > > A1= new List<List< int >>();
A1.Add( new List< int > { 1, 1, 1 });
A1.Add( new List< int >{ 1, 1, 1 });
A1.Add( new List< int >{ 1, 1, 1 });
int N1 = A1.Count;
int X1 = 4;
// Function Call
isReachable(A1, N1, X1);
}
} // This code is contributed by poojaagarwal2. |
// JavaScript code to implement the approach // Function to check whether paths // exists from (1, 1) to (N, N) such // that its sum is X function isReachable(A, N, X) {
// DP table for finding maximum and
// minimum path sum
let dp = new Array(N);
for (let i = 0; i < N; i++) {
dp[i] = new Array(N);
for (let j = 0; j < N; j++) {
dp[i][j] = new Array(2).fill(0);
}
}
// Base Case
dp[0][0][0] = A[0][0];
dp[0][0][1] = A[0][0];
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
// Base Case
if (i === 0 && j === 0) continue ;
// When coming from left is not
// possible
if (i === 0) {
dp[i][j][0] = dp[i][j - 1][0] + A[i][j - 1];
dp[i][j][1] = dp[i][j - 1][1] + A[i][j - 1];
}
// When coming from Left is not
// possible
else if (j === 0) {
dp[i][j][0] = dp[i - 1][j][0] + A[i - 1][j];
dp[i][j][1] = dp[i - 1][j][1] + A[i - 1][j];
}
// When Both coming from Left and Up
// possible
else {
dp[i][j][0] = Math.min(dp[i - 1][j][0] + A[i - 1][j],
dp[i][j - 1][0] + A[i][j - 1]);
dp[i][j][1] = Math.max(dp[i - 1][j][1] + A[i - 1][j],
dp[i][j - 1][1] + A[i][j - 1]);
}
}
}
// Minimum Path sum from (1, 1) to (N, N)
let minimumPathSum = dp[N - 1][N - 1][0];
// Maximum Path sum from (1, 1) to (N, N)
let maximumPathSum = dp[N - 1][N - 1][1];
// Number of cells in path from (1, 1) to (N, N)
let numberOfCells = 2 * N - 1;
// Parity of both numberOfCells from (1, 1)
// to (N, N) and X should be same and X
// should be in between range from
// minmumPathSum and maximumPathSum
if (numberOfCells % 2 === X % 2 && minimumPathSum <= X &&
maximumPathSum >= X) {
console.log( "Yes" );
} else {
console.log( "No" );
}
} // Driver Code let A = [ [ 1, 1, 1, 1 ],[ -1, 1, -1, -1 ],[ -1, 1, -1, 1 ],[ -1, -1, 1, 1 ] ]; let N = A.length;
let X = 3;
// Function Call
isReachable(A, N, X);
// Input 2
let A1= [ [ 1, 1, 1 ],[ 1, 1, 1 ],[ 1, 1, 1 ] ];
let N1 = A1.length;
let X1 = 4;
// Function Call
isReachable(A1, N1, X1);
// code by ksam24000 |
Yes No
Time Complexity: O(N * N)
Auxiliary Space: O(N * N)
Related Articles :
- Introduction to Dynamic Programming – Data Structures and Algorithms Tutorials
- Introduction to Matrix or Grid – Data Structure and Algorithm Tutorials