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++
// 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
// 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); } } |
Python3
# 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#
// 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
// 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
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!