2

I was going through a dp problem, there I have to initialize the matrix with default(-1) values for memoized solution. And felt the need.

We can initialize the 1D array in java like this => Arrays.fill(arr, -1) what for 2D array...?

Otherwise I have to run a nested for loop to initialize the matrix with default values, that includes more lines of code, and doesn't look appropriate when you are solving a dp problem.

4
  • Did you look at the source code for method fill in class Arrays? It contains a for loop, so in essence you are executing a loop even when you are initializing a one-dimensional array with that method. Commented Jun 24, 2024 at 7:13
  • Maybe you can adjust your algorithm such that you can make use of the default all-zeroes provided by new int[row][col] rather than doubly initialise the arrays. Commented Jun 24, 2024 at 10:31
  • It is a shame that Arrays.xxx() do not return the array as you could then have used matrix = setAll(new int[row][], i -> fill(new int[col], -1)); Commented Jun 24, 2024 at 10:33
  • Yeah ofc, inbuilf function is going to use a for loop for Array.fill() method, but it reduces the code and functinality, so again for the matrix it will be something like nested for loop. Commented Jun 25, 2024 at 10:25

3 Answers 3

2

Try the approach below:

public void fill2D(int[][] matrix, int value) {
    int m = matrix.length;
    int n = matrix[0].length;
    for (int i = 0; i < m * n; i++) {
        int row = i / n;
        int col = i % n;
        matrix[row][col] = value;
    }
}

Usage:

@Test
public void test() {
    int[][] matrix = new int[5][6];
    fill2D(matrix, -1);
    for (int[] row : matrix) {
        System.out.println(Arrays.toString(row));
    }
}

Benchmark test

private final int M = 500;
private final int N = 500;

@Benchmark
public void method1() {
    int[][] matrix = new int[M][N];
    for (int i = 0; i < M * N; i++) {
        int row = i / N;
        int col = i % N;
        matrix[row][col] = -1;
    }
}

@Benchmark
public void method2() {
    int[][] matrix = new int[M][N];
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            matrix[i][j] = -1;
        }
    }
}

@Benchmark
public void method3() {
    int[][] matrix = new int[M][N];
    for (int[] row : matrix) {
        Arrays.fill(row, -1);
    }
}

Result

Benchmark              Mode  Cnt  Score   Error  Units
BenchMarkTest.method1  avgt   20  0,600 ± 0,002  ms/op
BenchMarkTest.method2  avgt   20  0,191 ± 0,003  ms/op
BenchMarkTest.method3  avgt   20  0,216 ± 0,021  ms/op
Sign up to request clarification or add additional context in comments.

3 Comments

Mabye I'm just still half asleep, but doesn't this perform the same number of operations (actually, more operations) than a simple (and easier to read) nested loop?
@FedericoklezCulloca I measured the time using a benchmark, and this is faster than two nested loops.
Please share your benchmark. I'm not saying you're lying, I'm actually curious.
1

Try This:

int[][] dp = new int[rows][cols];

for (int[] row : dp) {
   Arrays.fill(row, -1);
}

Full Code:

    public static void main(String[] args) {
        int rows = 5;
        int cols = 5;
        int[][] dp = new int[rows][cols];

        for (int[] row : dp) {
            Arrays.fill(row, -1);
        }

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                System.out.print(dp[i][j] + " ");
            }
            System.out.println();
        }
    }

Output :

-1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 

Comments

1

You could combine Arrays.fill with Arrays.setAll using a function. Whether it is more readable or saves many lines compared to a simple loop is up to the viewer:

public static void main(String[] args) {

    int row = 4;
    int col = 4;
    int[][] matrix = new int[row][];

    IntFunction<int[]> func = i -> {
        int [] arr = new int[col];
        Arrays.fill(arr, -1);
        return arr;
    };

    Arrays.setAll(matrix, func::apply);

    System.out.println(Arrays.deepToString(matrix));

}

Or you can make use of streams and create your 2d array:

public static void main(String[] args) {

    int row = 4;
    int col = 4;

    int[][] matrixStream = IntStream.range(0, row).mapToObj(i -> IntStream.range(0, col).map(j -> -1).toArray())
                                    .toArray(int[][]::new);

    System.out.println(Arrays.deepToString(matrixStream));
}

But under the hood, all approaches use a loop

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.