I have a 2D array of 0's and 1's.
Every consecutive cells having 1's is considered as single object.
My task is to find the largest consecutive 1's for every row and also smallest consecutive 1's and get the difference of those.
Example:
oth Row --> 0 0 0 0 0
1st Row --> 0 0 1 0 0
2nd Row --> 0 0 1 0 1
3rd Row --> 1 1 1 0 1
4th Row --> 0 0 0 0 0
Explanation:
In 0th Row there are no 1's so no operation needed.
In 1st Row there is a single 1, so I am considering it as largest object of this row is 1.
In 2nd Row there is a 1 at position [2,2], I am considering it as largest object of this row is 1. Now the next 1 at position [2, 4], I am considering it as smallest object of this row is 1.
In 3rd Row there are three 1's at position [3,0],[3,1],[3,2], I am considering it as largest object of this row is 3. Now the next 1 at position [3, 4], I am considering it as smallest object of this row is 1.
In 4th row there are no 1's so no operation needed.
My task is to find the difference between the sum all largest objects and sum of all smallest objects.
In this example:
Sum of largest objects = 0 (0th row) + 1 (1st row) + 1 (2nd row) + 3 (3rd row) + 0 (4th row) = 5
Sum of smallest objects = 0 (0th row) + 0 (1st row) + 1 (2nd row) + 1 (3rd row) + 0 (4th row) = 2
Result = sum of largest - sum of smallest = 5 - 2 = 3.
I have comeup with below logic:
public static int process(int[][] array)
{
int result = 0;
// Get row and column size
int rows = array.length;
int cols = array[0].length;
// variables to store sum of large and small objects
int large = 0;
int small = 0;
for(int i=0; i<rows; i++) {
// variables to store large and small objects per row level
int l_count = 0;
int s_count = 0;
boolean valid = false;
for(int j=0; j<cols-1; j++) {
int curr = array[i][j];
int next = array[i][j+1];
// First occurrence of 1 is considered as large object
if(l_count == 0 && curr == 1) {
l_count++;
valid = true;
}
// consecutive 1's added to large count
if(valid && curr == next) {
l_count++;
} else {
valid = false;
}
// Get small count
if(!valid && curr == 1 || next == 1) {
s_count++;
}
}
// Add row level counts to large and small objects
large += l_count;
small += s_count;
}
result = large - small;
return result;
}
This is not working and giving wrong results, I am not able to find the needed logic to solve this problem.
To find the largest and smallest objects in each row you might first want to get a list of all objects in the row, then filter accordingly, that is have a function that does
0 0 0 0 0 -> []
0 0 1 0 0 -> [1]
0 0 1 0 1 -> [1,1]
1 1 1 0 1 -> [3,1]
0 0 0 0 0 -> []
After that you can use a function such as Collections.max(collection)
and Collections.min(Collection)
to get the maximum and minimum values. To account for the case in row 1 you could then check if(foundObjects.size < 2)
and set min
to 0
in that case.
A possible implementation for this, assuming you are using Java 1.8 or newer would be the following:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
class ObjectCalculator {
static int compute(int[][] array){
return Arrays.stream(array)
.map(ObjectCalculator::findObjects)
.mapToInt(objects -> {
int min, max;
if (objects.size() < 2) min = 0;
else min = Collections.min(objects);
if (objects.size() < 1) max = 0;
else max = Collections.max(objects);
return max - min;
}).sum();
}
static List<Integer> findObjects(int[] array) {
ArrayList<Integer> objects = new ArrayList<>();
int curSize = 0;
for(int i : array){
if(i == 1)curSize++;
else if(curSize > 0){
objects.add(curSize);
curSize = 0;
}
}
if(curSize > 0){
objects.add(curSize);
}
return objects;
}
}
Perhaps the changes below could solve your problem. Do not look over to the next element, just keep a count and keep working with the current element always.
public static int process(int[][] array)
{
int result = 0;
// Get row and column size
int rows = array.length;
int cols = array[0].length;
// variables to store sum of large and small objects
int large = 0;
int small = 0;
for(int i=0; i<rows; i++) {
// variables to store large and small objects per row level
int l_count = 0;
int s_count = 0;
int count = 0;
for(int j=0; j<cols; j++) {
if (array[i][j]) {
count++;
} else if (count > 0) {
if (count > l_count) {
l_count = count;
} else if (count < s_count || s_count == 0) {
s_count = count;
}
count = 0;
}
}
// Add row level counts to large and small objects
large += l_count;
small += s_count;
}
result = large - small;
return result;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.