-2

Can anyone help me out? I can't understand this programming question in Java? What does the greatest sum mean here in the matrix? In case 1, if I add each number from 5 in first row to 1 in last row, it doesn't add to 15. So why the output resulted in: 15 1 and 12 1 for case 2?

Problem#1 You will be given a square matrix of N rows and N columns (1 == N<= 1000) containing positive and negative integers with absolute value not larger than 1000. You are required to compute the greatest sum achievable by walking a path, starting at any cell of the matrix and always moving downwards or rightwards. Additionally, you have to report the number of times that value is achievable. N will be in the first line of the input. N lines follow with N integers each. You should output a single line with two integers separated by a single blank space: first one is the greatest sum, second one is the number of times this value can be reached.

Case 1:
For the input provided as follows:
5
3 1 -2 1 1
-6 -1 4 -1 -4
1 1 1 1 1
2 2 2 2 2
1 1 1 1 1

Output of the program will be:
15 1

Case 2:
For the input provided as follows:
3
1 1 1
2 2 2
3 3 3

Output of the program will be:
12 1

3 Answers3

3

The first 3 and 5 input is the size of the matrix 3 x 3 and 5 x 5 is should not counted for addition

as the rule says that you are not allowed to turn left or move up when traversing, below is a simple traversal right direction and bottom direction

12 means 1 + 2 + 3 + 3 + 3 times should be 1, because only in one path this values can be reached

enter image description here

15 means 3 + 1 -1 + 4 + 1 + 2 + 2 + 2 + 1 times should be 1, because only in path this value can be achieved

enter image description here

you need to program 2 x 2 kernel loop which will find the 2 biggest sum number and identify the direction of flow, then jump follow that direction and choose another 2 x 2 and keep on looping, no need to random direction

but, there is a trick here, if you get 2 big numbers there is a possibility that a second path you need to follow

to achieve the second path either you can go for double iteration or single iteration by processing two direction within a singe loop, a simple example of two directions

1  1  0  0  0
2  1  1  0  0
0  2  1  0  0
0  2  1  1  1
0  2  2  2  1

This is only a random solution I provided, but finding weights of the each 2x2 matrices and use tree based traversal, Convolution kernels.... etc should be the best way

Dickens A S
  • 3,824
  • 2
  • 22
  • 45
  • Does that mean I have to create a program with a "random" path that can find the greatest sum? – AfterProgram01 Mar 30 '20 at 06:22
  • Also, 3 + 1 -1 + 4 + 1 + 2 + 2 + 2 =14 not 15 – AfterProgram01 Mar 30 '20 at 06:25
  • I just need to clarify. If I input the same number as case 1 once again, does that mean it can result in anything since it's getting a sum of a random path? – AfterProgram01 Mar 30 '20 at 06:29
  • if you got your question answered please put a tick for accepted answer please :) – Dickens A S Mar 30 '20 at 06:35
  • in case 2: (12 1) you said that it should be 1 in 2nd integer because only in 1 path, 12 can be reached. But I can used this path also: 3 + 1 + 1 + 1 + 2 + 2 + 2=12. That means, it shouldn't be 1 – AfterProgram01 Mar 30 '20 at 06:36
  • @AfterProgram01 you should not add `3` is the first input to generate a `3 x 3` matrix, it could be any number which decides the size of the matrix – Dickens A S Mar 30 '20 at 07:00
  • *"when you loop for the second time"* Why would you need to loop more than once for a solution? What if there are 13 different paths to the same max result? E.g. a 3x3 matrix were all values are 2 should result in output `10 6`, i.e. the greatest sum is 10 and there are 6 different paths to get that sum. So you would loop 6 times to get all of them? That wouldn't perform for a 1000x1000 matrix! – Andreas Mar 30 '20 at 07:29
  • yes that is true, you can determine modulus/determinant of the minor matrices to check the weight of the adjacent minors and jump follow that direction, no need to start from zero again, so the second loop can start mid way also like tree branching for fractal magic, there are many solutions, we can use LAPACK also – Dickens A S Mar 30 '20 at 07:33
  • There is nothing deterministic you can do to pick a path, because you have no idea what comes further down any particular path, so you *must* consider all paths. Which can be done in a **single iteration** of the matrix. – Andreas Mar 30 '20 at 07:40
  • yes, that is possible, but if the big number falls bottom left corner, the `rule` is only bottom direction and right direction you should go, you are not allowed to turn left or move up – Dickens A S Mar 30 '20 at 07:43
  • Correct, but what are you trying to say with that comment? It doesn't contradict, clarify, or change anything I've said. You iterate once, from top-left to bottom-right, and you're done, with any 2x2 sub-matrix processing. – Andreas Mar 30 '20 at 07:49
  • yes I accept, simply pointed out, not need to start from scratch for next loop, I accept – Dickens A S Mar 30 '20 at 07:52
  • What "next loop"? If you have a "next loop", then you're iterating the matrix more than once, i.e. it's a sub-optimal solution. Did you miss the "single iteration" part of my earlier comment? – Andreas Mar 30 '20 at 07:56
0

This answer is a modification of the algorithm for the "Unique Paths" problem I wrote here: Trying to solve the “Unique Paths” problem, but getting the wrong answer. That other challenge had the same constraint, you can only move down and right, which is why a similar algorithm works.

In this case, we can start at the top-left. We need to maintain 2 arrays, one for the sum achievable for a given cell, and one for the count of paths to get that sum. We also need two variables for the highest sum/count achievable overall (maxSum and maxCount). All of these are initialized to 0's.

For each cell, there are 3 "paths" leading here, and we calculate what the sum/count would be for each of those paths (if possible), where row is an array of the matrix values for the current row being processed:

  • From above:
    The sum/count values are currently the accumulated values from the previous row. Since sum/count values were initialized to 0's, they can be used even when processing the first row.

    sumAbove = sum[col] + row[col]
    countAbove = count[col]
    
  • From the left:
    The sum/count values are currently the accumulated values from the previous cell of the current row, because we just updated that when iterating from left to right.

    sumLeft = sum[col - 1] + row[col]    or row[col] if col == 0
    countLeft = count[col - 1]           or 0 if col == 0
    
  • Starting here:

    sumStart = row[col]
    countStart = 1
    

We then find the highest sum of the three, and set the new sum[col] to that value. The new count[col] value will be the sum of the counts where the sum is the max, e.g. if all 3 sums are the same, then count[col] = countAbove + countLeft + countStart.

If the new sum[col] is higher than maxSum, then we update maxSum/maxCount to these new values. If the new sum[col] equals maxSum, we add the new count[col] to maxCount.

Let us use the following matrix as an example:

 3  1 -4  1  3
-6 -1  4 -1 -4
 1  1  1  1  1
-1  2  2  1  1
12 -5  1  1  0

We start with all 0's.

sum = { 0, 0, 0, 0, 0 }, count = { 0, 0, 0, 0, 0 }, maxSum = 0, maxCount = 0

Process the first row:

row: { 3, 1, -4, 1, 3 }
bestPath: { start, left, left, left/start, left }
sum = { 3, 4, 0, 1, 4 }, count = { 1, 1, 1, 2, 2 }, maxSum = 4, maxCount = 2

For the first three, there is one path to get those sums, i.e. starting at 0,0. For the last two, there are two paths to get those sums, i.e. starting at 0,0 or 3,0 (col,row). To clarify that, we showed the which path lead to the new values labeled bestPath.

Process the second row:

row: { -6, -1, 4, -1, -4 }
bestPath: { above, above, left, left, left }
sum = { -3, 3, 7, 6, 2 }, count = { 1, 1, 1, 1, 1 }, maxSum = 7, maxCount = 1

Process the third row:

row: { 1, 1, 1, 1, 1 }
bestPath: { start, above, above, above, above }
sum = { 1, 4, 8, 7, 3 }, count = { 1, 1, 1, 1, 1 }, maxSum = 8, maxCount = 1

Process the fourth row:

row: { -1, 2, 2, 1, 1 }
bestPath: { above, above, above, left, left }
sum = { 0, 6, 10, 11, 12 }, count = { 1, 1, 1, 1, 1 }, maxSum = 12, maxCount = 1

Process the fifth row:

row: { 12, -5, 1, 1, 0 }
bestPath: { start/above, left, above, above/left, above/left }
sum = { 12, 7, 11, 12, 12 }, count = { 2, 2, 1, 2, 3 }, maxSum = 12, maxCount = 9

Final result:

12 9

With an N x N matrix, this code has excellent O(m) time complexity, where m = N², i.e. the number of cells in the matrix, and O(N) aka O(sqrt m) storage complexity.

Andreas
  • 154,647
  • 11
  • 152
  • 247
0

Here's the code of implementation using python. Two matrices are used for testing.

def findMaximumPath(mat): 
    rows = cols = len(mat)
    count_list = []

    for i in range(rows):
        summ = 0
        mat_index = [rows-1, cols-1]
        curr_index = [0, i]
        summ = mat[curr_index[0]][curr_index[1]]

        while curr_index[0] != rows-1 and curr_index[1] != cols-1:
            if mat[curr_index[0]][curr_index[1]+1] > mat[curr_index[0]+1][curr_index[1]]:
                   curr_index[1] = curr_index[1] + 1
            else:
                   curr_index[0] = curr_index[0] + 1        

            summ += mat[curr_index[0]][curr_index[1]]
            #print(str(curr_index) + " Sum: " + str(summ))


        if curr_index[0] != rows-1 and curr_index[1] == cols-1:
            for i in range(curr_index[0]+1, rows):
                summ += mat[i][cols-1]
                #print(str(i) + "    Sum1: " +str(summ))

        if curr_index[0] == rows-1 and curr_index[1] != cols-1:
            for i in range(curr_index[1]+1, cols):
                summ += mat[rows-1][i]
                #print(str(i) + "    Sum2: " +str(summ))


        count_list.append(summ)

    max_sum = max(count_list)
    count = 0
    for element in count_list:  
        if(element == max_sum): 
            count+= 1

    print(count_list)
    print("Maximum Sum: " + str(max_sum))
    print("Number of Occurrences: " + str(count) + "\n")


mat1 = ([[3, 1, -2, 1, 1],
        [-6, -1, 4, -1, -4],
        [1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [1, 1, 1, 1, 1]]) 

mat2 = ([[1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]])

findMaximumPath(mat1)

findMaximumPath(mat2)

Output: Matrix 1: [15, 12, 10, 2, 1] Maximum Sum: 15 Number of Occurrences: 1

Matrix 2: [12, 9, 6] Maximum Sum: 12 Number of Occurrences: 1