You are given a matrix A representing a chessboard with N rows and M columns. Each square of the chessboard contains an integer representing a
points-based score. You have to place two rooks on the chessboard in such a way that they cannot attack each other and the sum of points on
their squares is maximal. Rooks in chess can attack each other only if they are in the same row or column.
For example, given a matrix as in the following picture:
we can place rooks in two different ways:
- One rook on A[00][00] = 1 and another rook on A[01][02] = 3. The sum of points on these squares is 4.
- One rook on A[00][02] = 4 and another rook on A[01][00] = 2. The sum of points on these squares is 6.
Your task is to find the maximum sum of two squares of the chessboards on which the rooks can be placed. In the example above, the answer is 6.
We cannot, for example, place the rooks at A[00][02] and A[01][02] (whose sum is 7), as they would attack each other.
Write a function:
function solution(A);
which, given a matrix A, returns the maximum sum that can be achieved by placing two non-attacking rooks
Examples:
- Given matrix A with two rows and two columns:
the function should return 6. We can achieve the maximum sum by selecting A[00][02] + A[01][00] = 4 + 2. The selected squares are marked in green
- Given matrix A with three rows and three columns:
the function should return 23. We can achieve the maximum sum by selecting A[00][00] + A[01][02] = 15 + 8. The selected squares are marked in green.
- Given matrix A with three rows and two columns:
the function should return 24. We can achieve the maximum sum by selecting A[00][00] + A[01][02] = 12 + 12 or A[00][02] + A[01][00] = 12 + 12. The latter
the solution is marked in green.
- Given matrix A with two rows and three columns:
the function should return 22. We can achieve the maximum sum by selecting A[00][02] + A[01][00] = 14 + 8. The selected squares are marked in green.
Write an efficient algorithm for the following assumptions
N and M are integers within the range [2..600];
each element of matrix A is an integer within the range [0..1,000,000,000].
I tried but don’t think it’s valid.
function solution(A) {
const N = A.length;
const M = A[0].length;
let maxSum = 0;
if(N > M){
for (let i = 0; i < N; i++) {
for (let j = i + 1; j < N; j++) {
for (let col1 = 0; col1 < M; col1++) {
for (let col2 = col1 + 1; col2 < M; col2++) {
if (col1 !== col2) {
const sum = A[i][col1] + A[j][col2];
maxSum = Math.max(maxSum, sum);
}
}
}
}
}
return maxSum;
}
for (let i = 0; i < N; i++) {
for (let j = i + 1; j < N; j++) {
for (let col1 = 0; col1 < M; col1++) {
for (let col2 = 0; col2 < M; col2++) {
if (col1 !== col2 && A[i][col1] !== A[j][col2]) {
maxSum = Math.max(maxSum, A[i][col1] + A[j][col2]);
}
}
}
}
}
return maxSum;
}
2
Answers
You can solve this problem in linear time.
Just iterate through the matrix row-by-row, and:
.
/
.We can build this fairly easily atop a function that creates a grid removing all the cells sharing a row or column with a given square. That function in turn can be written atop one that removes a given index from an array. It might looks like this:
Our main function first ensures that we can even get two non-attacking rooks, meaning that we have at least two rows of at least two columns. If not, we return
-Infinity
as a signal. Otherwise we find the maximum of two values: First, we skip the initial row, and recur on the remaining rows. Second, we take the maximum of testing each value in the first row, removing the associated row and column, and finding the largest remaining square and adding it to our cell value. The maximum of these two values is the best we can do.Note that this technique could easily be extended to find the maximum sum of all non-attacking rooks in the grid, simply be recurring rather than flattening and taking the maximum in the that second main branch. (I know that, as that’s what I wrote first on misreading the problem; the version presented here is only slightly simpler.)