Open In App

Find if path from top-left to bottom-right with sum X exists in given Matrix

Last Updated : 12 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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


Output

Yes
No

Time Complexity: O(N * N) 
Auxiliary Space: O(N * N)

Related Articles :



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads