Implementing 2D Array Algorithms
Every algorithm shape from Lesson 9.5 (sum/average, min/max, property checks, duplicates) extends to 2D arrays — applied to the whole grid, or to just one row, one column, or a subsection.
Sum a Row, Sum a Column
public static double getTotalForModule(int row, double[][] a)
{
double total = 0;
for (int col = 0; col < a[0].length; col++)
{
total = total + a[row][col];
}
return total;
}
public static double getTotalForSample(int col, double[][] a)
{
double total = 0;
for (int row = 0; row < a.length; row++)
{
total = total + a[row][col];
}
return total;
}
getTotalForModule sums one module's row across all samples; getTotalForSample sums one instant's column across all 4 modules (useful for spotting a simultaneous-spike brownout).
Max Across the Whole Array
public static double getPeakCurrent(double[][] a)
{
double peak = a[0][0];
for (int row = 0; row < a.length; row++)
{
for (int col = 0; col < a[0].length; col++)
{
if (a[row][col] > peak)
{
peak = a[row][col];
}
}
}
return peak;
}
Same seed-with-the-first-real-value rule from Lesson 9.5 — seeding with 0 would be wrong if every reading happened to be negative.
A Subsection Only
Loop bounds don't have to cover the whole array — narrowing them checks just a range of rows/columns, e.g. counting how many samples in a given module range exceeded a spike threshold:
public static int countSpikes(double threshold, double[][] a,
int rowStart, int rowEnd, int colStart, int colEnd)
{
int count = 0;
for (int row = rowStart; row <= rowEnd; row++)
{
for (int col = colStart; col <= colEnd; col++)
{
if (a[row][col] > threshold)
{
count++;
}
}
}
return count;
}
Duplicates Need 4 Nested Loops
A 1D duplicate check needs 2 nested loops (Lesson 9.5). A full 2D duplicate check needs 4: two to pick a starting cell (row, col), and two more to compare it against every cell that comes after it — later columns in the same row, plus every cell in every later row:
public static boolean hasDuplicateReading(double[][] a)
{
for (int row = 0; row < a.length; row++)
{
for (int col = 0; col < a[0].length; col++)
{
for (int row2 = row; row2 < a.length; row2++)
{
// ?: is the conditional operator, Lesson 5.5
int startCol = (row2 == row) ? col + 1 : 0;
for (int col2 = startCol; col2 < a[0].length; col2++)
{
if (a[row][col] == a[row2][col2])
{
return true;
}
}
}
}
}
return false;
}
The startCol trick avoids comparing a pair twice: within the same row (row2 == row), only look at columns after the candidate's own column; in a later row, every column is fair game.
Rotate/Reverse a Single Row or Column
Working on just one row (or one "virtual column" — a fixed column index across every row) really only touches one 1D array at a time, so the Ch.9 patterns carry over directly: rotating works like Lesson 9.7's ArrayList rotate (shift each element into the next slot, then wrap the last one around to the front); reversing works like Lesson 9.5's swap-from-both-ends.
public static void rotateRowRight(double[][] a, int row)
{
double last = a[row][a[0].length - 1];
for (int col = a[0].length - 1; col > 0; col--)
{
a[row][col] = a[row][col - 1];
}
a[row][0] = last;
}
public static void reverseRow(double[][] a, int row)
{
int left = 0;
int right = a[0].length - 1;
while (left < right)
{
double temp = a[row][left];
a[row][left] = a[row][right];
a[row][right] = temp;
left++;
right--;
}
}
Common Pitfalls
- Confusing "sum a row" with "sum a column." Fixing
rowand loopingcolsums a row; fixingcoland loopingrowsums a column — it's easy to write the wrong one by habit. - Forgetting the duplicate check's
startColtrick. Without it,col2always starts at0, so the innermost comparison hitsa[row][col] == a[row2][col2]withrow2 == rowandcol2 == col— a cell compared to itself — which is alwaystrue.hasDuplicateReadingwould report a duplicate on every array, even ones with none. - Using
<instead of<=on subsection bounds that are meant to be inclusive.countSpikes'srowEnd/colEndare inclusive bounds by design — a<would silently skip the last row/column.
Key Takeaways
- Every 1D array algorithm pattern (accumulator, min/max, property count, duplicates, rotate) extends to 2D — applied to the whole array, one row, one column, or a bounded subsection.
- Summing a row fixes the row index and loops columns; summing a column fixes the column index and loops rows.
- A full 2D duplicate check needs 4 nested loops, not 2 — two to pick the candidate cell, two more to scan every cell that comes after it without re-checking any pair.
- Rotating a single row (or a fixed-column "column slice") reuses Lesson 9.7's
ArrayListrotate pattern; reversing one reuses Lesson 9.5's swap-from-both-ends pattern.
Derived from csawesome-2026: unit-4-data-collections/4.13-implementing-2d-array-algorithms.md (CSA 4.13)