1. Brute Force — Flatten, Sort and Check All Windows
Intuition
Tag every element with list index, sort array. Check every subarray window [i, j]. If it contains at least one element from every list, track minimum range.
When to apply: When total elements count is very small (N <= 100).
Algorithm
- Step 1: Flatten all lists into (val, listId) pairs.
- Step 2: Sort combined array ascending.
- Step 3: For each i, for each j: track seen listIds.
- Step 4: If all k lists are seen, update best range if (val[j] - val[i]) is smaller.
- Step 5: Return minimal range.
#include <iostream>#include <vector>#include <algorithm>#include <unordered_set> class Solution {public: std::vector<int> smallestRange(std::vector<std::vector<int>>& nums) { int k = nums.size(); std::vector<std::pair<int, int>> combined; for (int i = 0; i < k; ++i) { for (int val : nums[i]) combined.push_back({val, i}); } std::sort(combined.begin(), combined.end()); int n = combined.size(); int bestStart = 0, bestEnd = 1e9; for (int i = 0; i < n; ++i) { std::unordered_set<int> seen; for (int j = i; j < n; ++j) { seen.insert(combined[j].second); if (seen.size() == k) { if (combined[j].first - combined[i].first < bestEnd - bestStart) { bestStart = combined[i].first; bestEnd = combined[j].first; } break; } } } return {bestStart, bestEnd}; }}; int main() { Solution sol; std::vector<std::vector<int>> nums = {{4, 10, 15, 24, 26}, {0, 9, 12, 20}, {5, 18, 22, 30}}; std::vector<int> res = sol.smallestRange(nums); std::cout << "[" << res[0] << ", " << res[1] << "]\n"; return 0;}Time & Space Complexity
- Time complexity:
O(N^2 * k)— O(N2) pairs of indices, each checking up to k elements. - Space complexity:
O(N)— Stores all combined elements in single array.
Why Brute Force Doesn't Scale:
With N = 1.75 * 105 total elements and k = 3500, an O(N * k) linear scan takes ~6 * 108 operations, which times out. Min-Heap performs O(N log k) ~ 2 * 106 operations.
For k = 3500, log2(k) ~ 12. Heap does 12 operations instead of 3,500 operations per step — a 290x speedup.