Delete Columns to Make Sorted
EasyUpdated: Aug 2, 2025
Practice on:
Problem
You are given an array of n strings strs, all of the same length.
The strings can be arranged such that there is one on each line, making a grid.
- For example,
strs = ["abc", "bce", "cae"]can be arranged as follows:
abc bce cae
You want to delete the columns that are not sorted lexicographically. In the above example (0-indexed), columns 0 ('a', 'b', 'c') and 2 ('c', 'e', 'e') are sorted, while column 1 ('b', 'c', 'a') is not, so you would delete column 1.
Return the number of columns that you will delete.
Examples
Example 1:
Input: strs = ["cba","daf","ghi"]
Output: 1
Explanation: The grid looks as follows:
cba
daf
ghi
Columns 0 and 2 are sorted, but column 1 is not, so you only need to delete 1 column.
Example 2:
Input: strs = ["a","b"]
Output: 0
Explanation: The grid looks as follows:
a
b
Column 0 is the only column and is sorted, so you will not delete any columns.
Example 3:
Input: strs = ["zyx","wvu","tsr"]
Output: 3
Explanation: The grid looks as follows:
zyx
wvu
tsr
All 3 columns are not sorted, so you will delete all 3.
Solution
Method 1 – Column-wise Lexicographical Check
Intuition
The key idea is to check each column of the grid formed by the strings. If any column is not sorted lexicographically from top to bottom, it must be deleted. We count such columns.
Approach
- Iterate over each column index.
- For each column, compare every character in that column with the character in the previous row.
- If any character is less than the character above it, increment the delete counter and break out of the check for that column.
- Return the total count of columns to delete.
Code
C++
class Solution {
public:
int minDeletionSize(vector<string>& strs) {
int ans = 0, n = strs.size(), m = strs[0].size();
for (int col = 0; col < m; ++col) {
for (int row = 1; row < n; ++row) {
if (strs[row][col] < strs[row-1][col]) {
++ans;
break;
}
}
}
return ans;
}
};
Go
func minDeletionSize(strs []string) int {
ans := 0
n, m := len(strs), len(strs[0])
for col := 0; col < m; col++ {
for row := 1; row < n; row++ {
if strs[row][col] < strs[row-1][col] {
ans++
break
}
}
}
return ans
}
Java
class Solution {
public int minDeletionSize(String[] strs) {
int ans = 0, n = strs.length, m = strs[0].length();
for (int col = 0; col < m; col++) {
for (int row = 1; row < n; row++) {
if (strs[row].charAt(col) < strs[row-1].charAt(col)) {
ans++;
break;
}
}
}
return ans;
}
}
Kotlin
class Solution {
fun minDeletionSize(strs: Array<String>): Int {
var ans = 0
val n = strs.size
val m = strs[0].length
for (col in 0 until m) {
for (row in 1 until n) {
if (strs[row][col] < strs[row-1][col]) {
ans++
break
}
}
}
return ans
}
}
Python
class Solution:
def minDeletionSize(self, strs: list[str]) -> int:
ans = 0
n, m = len(strs), len(strs[0])
for col in range(m):
for row in range(1, n):
if strs[row][col] < strs[row-1][col]:
ans += 1
break
return ans
Rust
impl Solution {
pub fn min_deletion_size(strs: Vec<String>) -> i32 {
let n = strs.len();
let m = strs[0].len();
let mut ans = 0;
for col in 0..m {
for row in 1..n {
if strs[row].as_bytes()[col] < strs[row-1].as_bytes()[col] {
ans += 1;
break;
}
}
}
ans
}
}
Complexity
- Time:
O(n * m)wherenis the number of strings andmis the length of each string. - Space:
O(1)(ignoring input storage).