Min and Max Element in Each Matrix Column
Column-wise minimum and maximum in a 2D matrix: algorithm, worked example, and complete programs in C, Java, and Python with complexity analysis.
Finding the minimum and maximum element in each column of a matrix requires the same two-loop traversal that TCS NQT, Infosys, and Wipro coding rounds test regularly in their online assessments.
The logic is compact: fix a column index, scan every row in that column from top to bottom, track the smallest and largest values encountered. Repeat for every column. No sorting needed, no extra data structures required.
What the Problem Asks
Given an m×n integer matrix, find and print two values for each column: the minimum element and the maximum element in that column.
Sample input (3×3 matrix):
1 4 9
3 5 1
2 8 5
Expected output:
Column 0: Min = 1, Max = 3
Column 1: Min = 4, Max = 8
Column 2: Min = 1, Max = 9
Verify each column manually before writing a single line of code:
- Column 0 contains elements 1, 3, 2. The minimum is 1 and the maximum is 3.
- Column 1 contains elements 4, 5, 8. The minimum is 4 and the maximum is 8.
- Column 2 contains elements 9, 1, 5. The minimum is 1 and the maximum is 9.
Column 2 is the instructive case: it starts with 9 (the largest value in the entire matrix) and also contains 1 (tied for the smallest). If your code initialises min_val from the first element of each column rather than from a fixed constant, it handles this case correctly without any special logic.
Algorithm: Fix the Column, Scan the Rows
The key insight is that column-wise traversal swaps the role of the two loop indices compared to row-wise traversal. The outer loop iterates over column indices; the inner loop iterates over row indices for that column.
Steps:
- Set the outer loop variable j from 0 to n-1, where n is the number of columns.
- For each column j, set
min_val = matrix[0][j]andmax_val = matrix[0][j]. - Set the inner loop variable i from 1 to m-1, where m is the number of rows.
- If
matrix[i][j]is less thanmin_val, updatemin_valtomatrix[i][j]. - If
matrix[i][j]is greater thanmax_val, updatemax_valtomatrix[i][j]. - After the inner loop ends, record or print
min_valandmax_valfor column j.
Walking through the example for column 2 step by step:
- Initialise:
min_val = 9,max_val = 9(frommatrix[0][2]). - Row 1:
matrix[1][2] = 1. Less than 9, somin_val = 1. Not greater, somax_valstays 9. - Row 2:
matrix[2][2] = 5. Not less than 1, not greater than 9. No updates. - Result: Min = 1, Max = 9. Matches expected output.
The initialisation on each outer-loop iteration from matrix[0][j] (not matrix[0][0]) is the single most common mistake. Initialising from matrix[0][0] works correctly only for j = 0; every other column may produce a wrong result depending on where its true minimum or maximum falls relative to matrix[0][0].
Programs in C and C++
C program
#include <stdio.h>
void findColMinMax(int matrix[100][100], int m, int n) {
int i, j, min_val, max_val;
for (j = 0; j < n; j++) {
min_val = matrix[0][j];
max_val = matrix[0][j];
for (i = 1; i < m; i++) {
if (matrix[i][j] < min_val)
min_val = matrix[i][j];
if (matrix[i][j] > max_val)
max_val = matrix[i][j];
}
printf("Column %d: Min = %d, Max = %d\n", j, min_val, max_val);
}
}
int main() {
int matrix[100][100] = {{1, 4, 9}, {3, 5, 1}, {2, 8, 5}};
findColMinMax(matrix, 3, 3);
return 0;
}
Output:
Column 0: Min = 1, Max = 3
Column 1: Min = 4, Max = 8
Column 2: Min = 1, Max = 9
C++ program
C++ provides std::min_element from <algorithm> for range-based operations, but placement evaluators and interview panels expect the manual comparison approach. The C++ version below uses that approach with cout instead of printf:
#include <iostream>
using namespace std;
void findColMinMax(int matrix[][3], int m, int n) {
for (int j = 0; j < n; j++) {
int minVal = matrix[0][j];
int maxVal = matrix[0][j];
for (int i = 1; i < m; i++) {
if (matrix[i][j] < minVal) minVal = matrix[i][j];
if (matrix[i][j] > maxVal) maxVal = matrix[i][j];
}
cout << "Column " << j << ": Min = " << minVal
<< ", Max = " << maxVal << "\n";
}
}
int main() {
int matrix[3][3] = {{1, 4, 9}, {3, 5, 1}, {2, 8, 5}};
findColMinMax(matrix, 3, 3);
return 0;
}
The C and C++ versions are structurally identical. The only differences are the I/O syntax and the variable declaration style.
Programs in Java and Python
Java program
public class ColMinMax {
static void findColMinMax(int[][] matrix, int m, int n) {
for (int j = 0; j < n; j++) {
int minVal = matrix[0][j];
int maxVal = matrix[0][j];
for (int i = 1; i < m; i++) {
if (matrix[i][j] < minVal) minVal = matrix[i][j];
if (matrix[i][j] > maxVal) maxVal = matrix[i][j];
}
System.out.println("Column " + j + ": Min = " + minVal
+ ", Max = " + maxVal);
}
}
public static void main(String[] args) {
int[][] matrix = {{1, 4, 9}, {3, 5, 1}, {2, 8, 5}};
findColMinMax(matrix, 3, 3);
}
}
Python program
Python’s built-in min() and max() accept any iterable. Extracting each column as a list and passing it to the built-ins produces the same result as the manual loop:
def find_col_min_max(matrix):
m = len(matrix)
n = len(matrix[0])
for j in range(n):
col_vals = [matrix[i][j] for i in range(m)]
print(f"Column {j}: Min = {min(col_vals)}, Max = {max(col_vals)}")
matrix = [[1, 4, 9], [3, 5, 1], [2, 8, 5]]
find_col_min_max(matrix)
When the interview or judge restricts built-in functions, replace the min(col_vals) and max(col_vals) calls with an explicit comparison loop that mirrors the C version. The logic is the same; only the syntax changes.
All four language implementations produce identical output. Run each one against the same 3×3 test case before submitting to any judge.
Time and Space Complexity
The complexity follows directly from the loop structure.
Time complexity: O(m×n). The outer loop runs n times (once per column). For each column the inner loop runs m-1 times (rows 1 through m-1). Total element comparisons: n × (m-1), which is O(m×n). Every element is visited exactly once. Doubling either dimension doubles the work; no element triggers more than two comparisons (one against min, one against max).
Scale the picture: a matrix with a thousand rows and a thousand columns has one million elements, all visited in a single pass. That fits inside the memory and time constraints of standard online judges without adjustment.
See the space complexity guide for how this O-notation scales with input and how to derive complexity from loop depth.
Auxiliary space: O(1). The only extra memory is min_val and max_val, two scalar variables reused on each outer-loop iteration. The matrix itself is input space, not auxiliary space. If you return a result array of size n (one min-max pair per column) rather than printing immediately, auxiliary space becomes O(n).
Column Traversal in Placement Rounds
Placement coding rounds rarely present the problem verbatim. The underlying traversal pattern appears wrapped in different instructions:
- “Return the index of the column with the largest sum” — same outer-inner structure, different aggregate.
- “Find the row with the minimum element” — swap the outer and inner loops; the logic is otherwise identical.
- “Check whether any two columns in a matrix are equal” — column-wise traversal with equality comparison instead of min/max.
- “Print the diagonal elements” — a related pattern where row and column indices increment together.
Recognising the column-traversal skeleton lets you adapt quickly in a timed assessment. The equilibrium index problem applies the same structural thinking to 1D arrays: fix a position, aggregate to the left, compare to the right. Problems like finding all symmetric pairs in an array extend the principle further: fix one element, scan the rest for a matching condition.
Column Traversal and Data Pipelines
The column-wise scan that runs cleanly on a 3×3 matrix is the same operation that runs over millions of rows in data pipelines: computing feature statistics, flagging outliers in sensor readings, normalising columns before feeding them to a model. The outer loop is a column selector; the inner loop is a row scanner. The mental model transfers directly.
If the O(m×n) derivation above took a moment to follow, TinkerLLM builds from exactly this foundation. The ₹299 entry point starts with data-processing exercises on tabular inputs, bridging from small matrix problems like this one to the kind of column-level feature engineering that appears in real ML pipelines, without compressing the reasoning steps between them.
Primary sources
Frequently asked questions
What is the time complexity of finding min and max in each column?
O(m*n) where m is the number of rows and n is the number of columns. Every element is visited exactly once, so the total comparison count equals the total number of elements in the matrix.
How does column-wise traversal differ from row-wise traversal?
In row-wise traversal the outer loop controls the row index and the inner loop moves across columns. In column-wise traversal the outer loop fixes the column index and the inner loop moves down through rows. The nested loops swap positions; the arithmetic inside remains identical.
Does this algorithm work for non-square matrices?
Yes. The outer loop runs from j = 0 to n-1 (column count) and the inner loop runs from i = 0 to m-1 (row count). If m does not equal n the algorithm still processes every column correctly regardless of aspect ratio.
What if all elements in a column are equal?
The minimum and maximum will both equal that repeated value. Initialising from matrix[0][j] and comparing subsequent rows finds no update to either variable, so both are reported as the same value. This is correct behaviour.
Can I use Python's built-in min() and max() for this?
Yes. Extract each column as a list using [matrix[i][j] for i in range(m)] and call min() and max() on it. Time complexity stays O(m*n); the built-ins handle the comparison loop internally.
Does initialising min and max from matrix[0][0] instead of matrix[0][j] cause a bug?
Yes, for any column other than column 0. If you always start from matrix[0][0], a column whose values all exceed that element will report the wrong minimum. Initialise from matrix[0][j] for whichever column j is being processed.
A self-paced playground for building with LLMs.
TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.
Try TinkerLLM (₹299 launch)