Find total number of paths in a matrix of 0's and 1's

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












I am working on a program which states that:



You are given a 2-D matrix with M rows and N columns.You are initially positioned at (0,0) which is the top-left cell in the array. You are allowed to move either right or downwards. The array is filled with 1’s and 0’s. A 1 indicates that you can move through that cell, a 0 indicates that you cannot move through that cell. Return the number of paths from top-left cell to bottom-right cell.(i.e. (0,0)to(M-1,N-1)). Since answer can be large thus you have to return ans%(10^9+7).



static int count(int a, int i, int j) 
int rows = a.length;
int cols = a[0].length;
if(a[i][j] == 0) return 0;
if (i == rows - 1 && j == cols - 1)
return a[i][j];
else if (i == rows - 1)
return a[i][j + 1];
else if (j == cols - 1)
return a[i + 1][j];
else if (a[i][j] == 1)
return count(a, i + 1, j) + count(a, i, j + 1);
else
return 0;



How can we improve the performance of this program?







share|improve this question





















  • @Vogel612, I updated my post now, actually the issue is with performance now, the test cases are fine now.
    – user3181365
    Feb 27 at 22:32










  • You'll receive better reviews if you show a complete example. For example, I recommend that you edit to show the necessary #include lines, and a main() that shows how to call your function (you should probably include your test cases there). It can really help reviewers if they are able to compile and run your program.
    – Toby Speight
    Feb 28 at 8:08
















up vote
1
down vote

favorite












I am working on a program which states that:



You are given a 2-D matrix with M rows and N columns.You are initially positioned at (0,0) which is the top-left cell in the array. You are allowed to move either right or downwards. The array is filled with 1’s and 0’s. A 1 indicates that you can move through that cell, a 0 indicates that you cannot move through that cell. Return the number of paths from top-left cell to bottom-right cell.(i.e. (0,0)to(M-1,N-1)). Since answer can be large thus you have to return ans%(10^9+7).



static int count(int a, int i, int j) 
int rows = a.length;
int cols = a[0].length;
if(a[i][j] == 0) return 0;
if (i == rows - 1 && j == cols - 1)
return a[i][j];
else if (i == rows - 1)
return a[i][j + 1];
else if (j == cols - 1)
return a[i + 1][j];
else if (a[i][j] == 1)
return count(a, i + 1, j) + count(a, i, j + 1);
else
return 0;



How can we improve the performance of this program?







share|improve this question





















  • @Vogel612, I updated my post now, actually the issue is with performance now, the test cases are fine now.
    – user3181365
    Feb 27 at 22:32










  • You'll receive better reviews if you show a complete example. For example, I recommend that you edit to show the necessary #include lines, and a main() that shows how to call your function (you should probably include your test cases there). It can really help reviewers if they are able to compile and run your program.
    – Toby Speight
    Feb 28 at 8:08












up vote
1
down vote

favorite









up vote
1
down vote

favorite











I am working on a program which states that:



You are given a 2-D matrix with M rows and N columns.You are initially positioned at (0,0) which is the top-left cell in the array. You are allowed to move either right or downwards. The array is filled with 1’s and 0’s. A 1 indicates that you can move through that cell, a 0 indicates that you cannot move through that cell. Return the number of paths from top-left cell to bottom-right cell.(i.e. (0,0)to(M-1,N-1)). Since answer can be large thus you have to return ans%(10^9+7).



static int count(int a, int i, int j) 
int rows = a.length;
int cols = a[0].length;
if(a[i][j] == 0) return 0;
if (i == rows - 1 && j == cols - 1)
return a[i][j];
else if (i == rows - 1)
return a[i][j + 1];
else if (j == cols - 1)
return a[i + 1][j];
else if (a[i][j] == 1)
return count(a, i + 1, j) + count(a, i, j + 1);
else
return 0;



How can we improve the performance of this program?







share|improve this question













I am working on a program which states that:



You are given a 2-D matrix with M rows and N columns.You are initially positioned at (0,0) which is the top-left cell in the array. You are allowed to move either right or downwards. The array is filled with 1’s and 0’s. A 1 indicates that you can move through that cell, a 0 indicates that you cannot move through that cell. Return the number of paths from top-left cell to bottom-right cell.(i.e. (0,0)to(M-1,N-1)). Since answer can be large thus you have to return ans%(10^9+7).



static int count(int a, int i, int j) 
int rows = a.length;
int cols = a[0].length;
if(a[i][j] == 0) return 0;
if (i == rows - 1 && j == cols - 1)
return a[i][j];
else if (i == rows - 1)
return a[i][j + 1];
else if (j == cols - 1)
return a[i + 1][j];
else if (a[i][j] == 1)
return count(a, i + 1, j) + count(a, i, j + 1);
else
return 0;



How can we improve the performance of this program?









share|improve this question












share|improve this question




share|improve this question








edited Feb 27 at 22:31
























asked Feb 27 at 22:24









user3181365

1093




1093











  • @Vogel612, I updated my post now, actually the issue is with performance now, the test cases are fine now.
    – user3181365
    Feb 27 at 22:32










  • You'll receive better reviews if you show a complete example. For example, I recommend that you edit to show the necessary #include lines, and a main() that shows how to call your function (you should probably include your test cases there). It can really help reviewers if they are able to compile and run your program.
    – Toby Speight
    Feb 28 at 8:08
















  • @Vogel612, I updated my post now, actually the issue is with performance now, the test cases are fine now.
    – user3181365
    Feb 27 at 22:32










  • You'll receive better reviews if you show a complete example. For example, I recommend that you edit to show the necessary #include lines, and a main() that shows how to call your function (you should probably include your test cases there). It can really help reviewers if they are able to compile and run your program.
    – Toby Speight
    Feb 28 at 8:08















@Vogel612, I updated my post now, actually the issue is with performance now, the test cases are fine now.
– user3181365
Feb 27 at 22:32




@Vogel612, I updated my post now, actually the issue is with performance now, the test cases are fine now.
– user3181365
Feb 27 at 22:32












You'll receive better reviews if you show a complete example. For example, I recommend that you edit to show the necessary #include lines, and a main() that shows how to call your function (you should probably include your test cases there). It can really help reviewers if they are able to compile and run your program.
– Toby Speight
Feb 28 at 8:08




You'll receive better reviews if you show a complete example. For example, I recommend that you edit to show the necessary #include lines, and a main() that shows how to call your function (you should probably include your test cases there). It can really help reviewers if they are able to compile and run your program.
– Toby Speight
Feb 28 at 8:08










2 Answers
2






active

oldest

votes

















up vote
1
down vote













Recursion is not recommended. First, you would likely end up repeating calculations for cells that are approached from multiple paths. Second, the call stack would be as deep as the longest path, and you could easily crash with a StackOverflowError for a large maze.



Instead, I recommend using dynamic-programming, building a 2D table where each entry is the number of paths from the start to that location. Every paths[r][c] is calculated exactly once, and in an order that is gentle to the cache.



public static int count(int a) 
int paths = new int[a.length][a[0].length];
if ((paths[0][0] = a[0][0]) == 0)
return 0;

for (int c = 1; c < a[0].length; c++)
paths[0][c] = a[0][c] * paths[0][c - 1];

for (int r = 1; r < a.length; r++)
paths[r][0] = a[r][0] * paths[r - 1][0];
for (int c = 1; c < a[r].length; c++)
paths[r][c] = a[r][c] * (paths[r - 1][c] + paths[r][c - 1]);


return paths[a.length - 1][a[0].length - 1];



You can even even build the paths one row at a time, while the maze a is being loaded. Furthermore, it is possible to modify the code to use less memory, since only the last two rows of paths are relevant at any given time. However, for simplicity, I haven't done that here: if you can afford to keep the entire a in memory, then you can probably also afford to keep another 2D array of the same size.






share|improve this answer






























    up vote
    0
    down vote













    You are likely recalculating the same cell multiple times. For example, let's say you have a 3x3 grid where all cells are 1. You will calculate count(a, 1, 1) twice: once as part of count(a, 0, 1), and once as part of count(a, 1, 0).



    You should instead keep track of those values you have calculated so far, and return those where available. For example:



    static int count(int a, int i, int j) 
    return count(a, i, j, new int[a.length][a[0].length]);


    static int count(int a, int i, int j, int results)
    if (results[i][j] != 0)
    return results[i][j];

    int rows = a.length;
    int cols = a[0].length;
    int ret;
    if(a[i][j] == 0)
    ret = 0;
    else if (i == rows - 1 && j == cols - 1)
    ret = a[i][j];
    else if (i == rows - 1)
    ret = a[i][j + 1];
    else if (j == cols - 1)
    ret = a[i + 1][j];
    else if (a[i][j] == 1)
    ret = count(a, i + 1, j, results) + count(a, i, j + 1, results);
    else
    ret = 0;
    results[i][j] = ret;
    return ret;






    share|improve this answer























      Your Answer




      StackExchange.ifUsing("editor", function ()
      return StackExchange.using("mathjaxEditing", function ()
      StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
      StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
      );
      );
      , "mathjax-editing");

      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "196"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );








       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188487%2ffind-total-number-of-paths-in-a-matrix-of-0s-and-1s%23new-answer', 'question_page');

      );

      Post as a guest






























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      1
      down vote













      Recursion is not recommended. First, you would likely end up repeating calculations for cells that are approached from multiple paths. Second, the call stack would be as deep as the longest path, and you could easily crash with a StackOverflowError for a large maze.



      Instead, I recommend using dynamic-programming, building a 2D table where each entry is the number of paths from the start to that location. Every paths[r][c] is calculated exactly once, and in an order that is gentle to the cache.



      public static int count(int a) 
      int paths = new int[a.length][a[0].length];
      if ((paths[0][0] = a[0][0]) == 0)
      return 0;

      for (int c = 1; c < a[0].length; c++)
      paths[0][c] = a[0][c] * paths[0][c - 1];

      for (int r = 1; r < a.length; r++)
      paths[r][0] = a[r][0] * paths[r - 1][0];
      for (int c = 1; c < a[r].length; c++)
      paths[r][c] = a[r][c] * (paths[r - 1][c] + paths[r][c - 1]);


      return paths[a.length - 1][a[0].length - 1];



      You can even even build the paths one row at a time, while the maze a is being loaded. Furthermore, it is possible to modify the code to use less memory, since only the last two rows of paths are relevant at any given time. However, for simplicity, I haven't done that here: if you can afford to keep the entire a in memory, then you can probably also afford to keep another 2D array of the same size.






      share|improve this answer



























        up vote
        1
        down vote













        Recursion is not recommended. First, you would likely end up repeating calculations for cells that are approached from multiple paths. Second, the call stack would be as deep as the longest path, and you could easily crash with a StackOverflowError for a large maze.



        Instead, I recommend using dynamic-programming, building a 2D table where each entry is the number of paths from the start to that location. Every paths[r][c] is calculated exactly once, and in an order that is gentle to the cache.



        public static int count(int a) 
        int paths = new int[a.length][a[0].length];
        if ((paths[0][0] = a[0][0]) == 0)
        return 0;

        for (int c = 1; c < a[0].length; c++)
        paths[0][c] = a[0][c] * paths[0][c - 1];

        for (int r = 1; r < a.length; r++)
        paths[r][0] = a[r][0] * paths[r - 1][0];
        for (int c = 1; c < a[r].length; c++)
        paths[r][c] = a[r][c] * (paths[r - 1][c] + paths[r][c - 1]);


        return paths[a.length - 1][a[0].length - 1];



        You can even even build the paths one row at a time, while the maze a is being loaded. Furthermore, it is possible to modify the code to use less memory, since only the last two rows of paths are relevant at any given time. However, for simplicity, I haven't done that here: if you can afford to keep the entire a in memory, then you can probably also afford to keep another 2D array of the same size.






        share|improve this answer

























          up vote
          1
          down vote










          up vote
          1
          down vote









          Recursion is not recommended. First, you would likely end up repeating calculations for cells that are approached from multiple paths. Second, the call stack would be as deep as the longest path, and you could easily crash with a StackOverflowError for a large maze.



          Instead, I recommend using dynamic-programming, building a 2D table where each entry is the number of paths from the start to that location. Every paths[r][c] is calculated exactly once, and in an order that is gentle to the cache.



          public static int count(int a) 
          int paths = new int[a.length][a[0].length];
          if ((paths[0][0] = a[0][0]) == 0)
          return 0;

          for (int c = 1; c < a[0].length; c++)
          paths[0][c] = a[0][c] * paths[0][c - 1];

          for (int r = 1; r < a.length; r++)
          paths[r][0] = a[r][0] * paths[r - 1][0];
          for (int c = 1; c < a[r].length; c++)
          paths[r][c] = a[r][c] * (paths[r - 1][c] + paths[r][c - 1]);


          return paths[a.length - 1][a[0].length - 1];



          You can even even build the paths one row at a time, while the maze a is being loaded. Furthermore, it is possible to modify the code to use less memory, since only the last two rows of paths are relevant at any given time. However, for simplicity, I haven't done that here: if you can afford to keep the entire a in memory, then you can probably also afford to keep another 2D array of the same size.






          share|improve this answer















          Recursion is not recommended. First, you would likely end up repeating calculations for cells that are approached from multiple paths. Second, the call stack would be as deep as the longest path, and you could easily crash with a StackOverflowError for a large maze.



          Instead, I recommend using dynamic-programming, building a 2D table where each entry is the number of paths from the start to that location. Every paths[r][c] is calculated exactly once, and in an order that is gentle to the cache.



          public static int count(int a) 
          int paths = new int[a.length][a[0].length];
          if ((paths[0][0] = a[0][0]) == 0)
          return 0;

          for (int c = 1; c < a[0].length; c++)
          paths[0][c] = a[0][c] * paths[0][c - 1];

          for (int r = 1; r < a.length; r++)
          paths[r][0] = a[r][0] * paths[r - 1][0];
          for (int c = 1; c < a[r].length; c++)
          paths[r][c] = a[r][c] * (paths[r - 1][c] + paths[r][c - 1]);


          return paths[a.length - 1][a[0].length - 1];



          You can even even build the paths one row at a time, while the maze a is being loaded. Furthermore, it is possible to modify the code to use less memory, since only the last two rows of paths are relevant at any given time. However, for simplicity, I haven't done that here: if you can afford to keep the entire a in memory, then you can probably also afford to keep another 2D array of the same size.







          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Feb 28 at 2:37


























          answered Feb 28 at 1:20









          200_success

          123k14142399




          123k14142399






















              up vote
              0
              down vote













              You are likely recalculating the same cell multiple times. For example, let's say you have a 3x3 grid where all cells are 1. You will calculate count(a, 1, 1) twice: once as part of count(a, 0, 1), and once as part of count(a, 1, 0).



              You should instead keep track of those values you have calculated so far, and return those where available. For example:



              static int count(int a, int i, int j) 
              return count(a, i, j, new int[a.length][a[0].length]);


              static int count(int a, int i, int j, int results)
              if (results[i][j] != 0)
              return results[i][j];

              int rows = a.length;
              int cols = a[0].length;
              int ret;
              if(a[i][j] == 0)
              ret = 0;
              else if (i == rows - 1 && j == cols - 1)
              ret = a[i][j];
              else if (i == rows - 1)
              ret = a[i][j + 1];
              else if (j == cols - 1)
              ret = a[i + 1][j];
              else if (a[i][j] == 1)
              ret = count(a, i + 1, j, results) + count(a, i, j + 1, results);
              else
              ret = 0;
              results[i][j] = ret;
              return ret;






              share|improve this answer



























                up vote
                0
                down vote













                You are likely recalculating the same cell multiple times. For example, let's say you have a 3x3 grid where all cells are 1. You will calculate count(a, 1, 1) twice: once as part of count(a, 0, 1), and once as part of count(a, 1, 0).



                You should instead keep track of those values you have calculated so far, and return those where available. For example:



                static int count(int a, int i, int j) 
                return count(a, i, j, new int[a.length][a[0].length]);


                static int count(int a, int i, int j, int results)
                if (results[i][j] != 0)
                return results[i][j];

                int rows = a.length;
                int cols = a[0].length;
                int ret;
                if(a[i][j] == 0)
                ret = 0;
                else if (i == rows - 1 && j == cols - 1)
                ret = a[i][j];
                else if (i == rows - 1)
                ret = a[i][j + 1];
                else if (j == cols - 1)
                ret = a[i + 1][j];
                else if (a[i][j] == 1)
                ret = count(a, i + 1, j, results) + count(a, i, j + 1, results);
                else
                ret = 0;
                results[i][j] = ret;
                return ret;






                share|improve this answer

























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  You are likely recalculating the same cell multiple times. For example, let's say you have a 3x3 grid where all cells are 1. You will calculate count(a, 1, 1) twice: once as part of count(a, 0, 1), and once as part of count(a, 1, 0).



                  You should instead keep track of those values you have calculated so far, and return those where available. For example:



                  static int count(int a, int i, int j) 
                  return count(a, i, j, new int[a.length][a[0].length]);


                  static int count(int a, int i, int j, int results)
                  if (results[i][j] != 0)
                  return results[i][j];

                  int rows = a.length;
                  int cols = a[0].length;
                  int ret;
                  if(a[i][j] == 0)
                  ret = 0;
                  else if (i == rows - 1 && j == cols - 1)
                  ret = a[i][j];
                  else if (i == rows - 1)
                  ret = a[i][j + 1];
                  else if (j == cols - 1)
                  ret = a[i + 1][j];
                  else if (a[i][j] == 1)
                  ret = count(a, i + 1, j, results) + count(a, i, j + 1, results);
                  else
                  ret = 0;
                  results[i][j] = ret;
                  return ret;






                  share|improve this answer















                  You are likely recalculating the same cell multiple times. For example, let's say you have a 3x3 grid where all cells are 1. You will calculate count(a, 1, 1) twice: once as part of count(a, 0, 1), and once as part of count(a, 1, 0).



                  You should instead keep track of those values you have calculated so far, and return those where available. For example:



                  static int count(int a, int i, int j) 
                  return count(a, i, j, new int[a.length][a[0].length]);


                  static int count(int a, int i, int j, int results)
                  if (results[i][j] != 0)
                  return results[i][j];

                  int rows = a.length;
                  int cols = a[0].length;
                  int ret;
                  if(a[i][j] == 0)
                  ret = 0;
                  else if (i == rows - 1 && j == cols - 1)
                  ret = a[i][j];
                  else if (i == rows - 1)
                  ret = a[i][j + 1];
                  else if (j == cols - 1)
                  ret = a[i + 1][j];
                  else if (a[i][j] == 1)
                  ret = count(a, i + 1, j, results) + count(a, i, j + 1, results);
                  else
                  ret = 0;
                  results[i][j] = ret;
                  return ret;







                  share|improve this answer















                  share|improve this answer



                  share|improve this answer








                  edited Feb 28 at 1:09









                  200_success

                  123k14142399




                  123k14142399











                  answered Feb 27 at 22:51









                  Joe C

                  58919




                  58919






















                       

                      draft saved


                      draft discarded


























                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188487%2ffind-total-number-of-paths-in-a-matrix-of-0s-and-1s%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Popular posts from this blog

                      Greedy Best First Search implementation in Rust

                      Function to Return a JSON Like Objects Using VBA Collections and Arrays

                      C++11 CLH Lock Implementation