Algorithm
This is the part when you only use pen and paper. Basically, I understood the problem as follow:
Given a matrix with n rows and m columns of Integer
1:
Find the highest value
All entries in the rows and columns holding the highest value must have its value set at 0
Print the updated matrix
Assumption
I made the following assumptions:
In n is not necessarily equal to m. For example, you can have the array:
Valid Input
1 2 3 4 5 6
7 8 9 10 11 12
7 8 12 5 6 4
which must give, as 12 is the highest value:
Output
1 2 0 4 5 0
0 0 0 0 0 0
0 0 0 0 0 0
The matrix is consistent: every row has m columns and every column has n rows. For example, such input is incorrect:
Incorrect input
1 2 3
7 8 9 10
7 8
Logic
At this stage, you're still using pen, paper and Google only!
In my problem understanding, I splitted in three parts as I thought this is how you understood the problem. This is the mathematics understanding. Now let's convert it into a more Java understanding. First of all, we need to translate some vocabulary:
Mathematics wording | Java wording
--------------------|---------------------
matrix | 2-dimensional array
Integer | int (primitive type)
which gives in Java way:
Given an 2-dimensional int[][]
array:
Find the highest value
Find the rows and columns holding the highest value
Update the array by setting the value to 0 for the rows and columns found in 2.
Print the array
In the specific case of my solution, I combine 1. + 2. and I combined 3. + 4.
What you did
Let's open your favorite IDE and compare my analysis with your input:
Find the highest value: OK here: : you use the variable max
and scan the matrix to find the maximum value. You also assumed that the matrix could be rectangle (n rows and m columns with n != m). So it's good
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
if (array2[i][j] > max) {
max = array2[i][j];
}
}
}
Find the rows and columns: ERROR here, as mentioned by ccp-beginner, when you found a the highest value, you erase (set to zero) the value for the whole column and whole row but maybe the same highest value was stored somewhere else in this row or column
for (k = 0; k < array2.length; k++) {
for (m = 0; m < array2[k].length; m++) {
if (array2[k][m] == max) {
countIndexHorizontal = k;
countIndexVertical = m;
// additional operation defined in 3.
}
// in ccp-beginner example of
// 2, 2
// 1, 1
// if k=0 and m=0, you'll update the value
// of the first row and first column giving:
// 0, 0
// 0, 1
// but when k=0, m=1, you'll find 0 instead
// of 2 so your program will consider that
// this row / column does not contain the
// highest value
}
}
I assume here the
- countIndexHorizontal = row
- countIndexVertical = column
So you need to keep track of the rows and columns when you're setting the values to 0.
Update the array: ERROR here (cf ccp-beginner's answer)
for (x = 0; x < array2.length; x++) {
for (int j = 0; j < array2[x].length; j++) {
if (countIndexVertical == x || j == countIndexHorizontal) {
array2[x][j] = 0;
// In your example:
// 1 2 3 4
// 1 2 20 4
// 1 20 2 4
// 1 2 3 4
// and if countIndexVertical=2 and countIndexHorizontal=1
// (the 20 of the second row between 2 and 4), you'll have
// 1 0 3 4
// 1 0 20 4
// 0 0 0 0
// 1 0 3 4
// instead of
// 1 2 0 4
// 0 0 0 0
// 1 20 0 4
// 1 2 0 4
}
}
}
you got confused between countIndexVertical
and countIndexHorizontal
, as you have
You should had (please notice the swapping)
if (countIndexHorizontal == x || j == countIndexVertical) {
array2[x][j] = 0;
}
Print the array: OK here, nothing special to mention
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
System.out.print(array2[i][j] + " ");
}
System.out.println();
}
The problem
Basically, what you need is how to store the rows and the columns containing the highest value. At first, we could be tempted to use array again right, like
int[] rowsContainingHighestValue;
int[] columnsContainingHighestValue;
But you don't know how many highest value you'll encounter so you need something to store multiple value with a dynamic size: I'll use List
.
Some Java point
The rowsContainingHighestValue
and columnsContainingHighestValue
become:
List<Integer> rowsContainingHighestValue = new ArrayList<>();
List<Integer> columnsContainingHighestValue = new ArrayList<>();
You may want to have a look at the following point:
- Why
List
instead of array
?
- My objects are declared as
List
but I instantiate2 with ArrayList
: What is a Interface
and what is a Class
- Why I used
List<Integer>
instead of List<int>
- What is the difference between
Integer
and int
One solution
- loop through for the matrix to fetch the maximum value and store all rows and columns holding this value instead of a single row/column combination (
countIndexHorizontal
and countIndexVertical
)
- If a new maximum value is found, store it (like you did) AND store the current row and column index
- If a value is identical to the current maximum value (e.g. you have
20
twice), then append the row and column index to the existing respective row / column list
- loop a second time for updating and printing the value
- it's basically combining your two last double-loop: if the scanned element belongs to a row or a column holding the maximum value, then the value must be set at 0 (exactly the way you did but shorter as I already have the list of rows / columns)
- once the values are properly updated, just proceed to a simple printing
Which in code gives:
public static void main(String[] args) {
int[][] array2 = {
{1, 2, 3, 4},
{1, 2, 20, 4},
{1, 20, 2, 4},
{1, 2, 3, 4}
};
// find the maximum value and store its position:
// It's List instead of a single value as multiple
// rows and columns can hold the same maximum value
List<Integer> rowsWithMaxValue = new ArrayList<>();
List<Integer> colsWithMaxValue = new ArrayList<>();
int maxValue = Integer.MIN_VALUE;
// First matrix-scan to fetch the maximum value and the
// row(s) and column(s) to set the value at 0
for (int row = 0; row < array2.length; row++) {
for (int col = 0; col < array2[row].length; col++) {
// get the current value
int value = array2[row][col];
// found a new maximum or an existing one?
if (value > maxValue) {
// this is a new maximum value, we can reset
// the list as the previous rows and columns
// are not relevant anymore
maxValue = value;
rowsWithMaxValue = new ArrayList<>();
colsWithMaxValue = new ArrayList<>();
rowsWithMaxValue.add(row);
colsWithMaxValue.add(col);
} else if (value == maxValue) {
// The same value (like 20) is found again
// so multiple rows and columns will have
// their value set at 0
rowsWithMaxValue.add(row);
colsWithMaxValue.add(col);
}
}
}
// Second matrix-scan for updating the values and printing
for (int row = 0; row < array2.length; row++) {
for (int col = 0; col < array2[row].length; col++) {
// is it in a forbidden row? If yes, set the value
// at zero. One of the condition (row or column) is
// enough to have its value set at 0
if (rowsWithMaxValue.contains(row) || colsWithMaxValue.contains(col)) {
array2[row][col] = 0;
}
// Simply print the value
System.out.print(array2[row][col] + " ");
}
System.out.println();
}
}
1Integer in the mathematics meaning: positive or negative number without decimal
2I won't explain instantiation here. Feel free to google it