Sorting is often the first step in solving a problem, not the solution itself. A sorted array enables binary search, two pointers, and greedy approaches. The key skill is knowing when to sort and how to define the sort order.
Pattern Recognition Signals:
Problem mentions “minimum” or “maximum”
Need to pair elements optimally
Need to process elements in a specific order
Two pointers would work “if only the array were sorted”
Problem: Select maximum number of non-overlapping intervals.Key Insight: Sort by end time. Greedy works because finishing early leaves room for more.
int maxNonOverlapping(vector<pair<int, int>>& intervals) { // Sort by end time sort(intervals.begin(), intervals.end(), [](auto& a, auto& b) { return a.second < b.second; }); int count = 0; int lastEnd = INT_MIN; for (auto& [start, end] : intervals) { if (start >= lastEnd) { count++; lastEnd = end; } } return count;}
Problem: Arrange elements to maximize/minimize some combined result.Example: Concatenate numbers to form largest number.
string largestNumber(vector<int>& nums) { vector<string> strs; for (int n : nums) strs.push_back(to_string(n)); // Key insight: compare "ab" vs "ba" sort(strs.begin(), strs.end(), [](const string& a, const string& b) { return a + b > b + a; }); if (strs[0] == "0") return "0"; // All zeros string result; for (const string& s : strs) result += s; return result;}// Example: [3, 30, 34] → "34330"
When: You need to preserve relative order of equal elements.
vector<pair<int, string>> data = {{3, "a"}, {1, "b"}, {3, "c"}, {1, "d"}};stable_sort(data.begin(), data.end(), [](auto& a, auto& b) { return a.first < b.first;});// data = {{1, "b"}, {1, "d"}, {3, "a"}, {3, "c"}}// Notice: "b" before "d" and "a" before "c" (original order preserved)
Mistake 1: Inconsistent Comparator
Comparator must define a strict weak ordering:
a < a must be false (irreflexivity)
If a < b then b < a must be false (antisymmetry)
If a < b and b < c then a < c (transitivity)
// WRONG: Can cause undefined behaviorsort(arr.begin(), arr.end(), [](int a, int b) { return a <= b; // Using <= instead of <});// CORRECTsort(arr.begin(), arr.end(), [](int a, int b) { return a < b;});
Mistake 2: Sorting Changes Index Mapping
If you need original indices, create pairs:
vector<pair<int, int>> indexed(n);for (int i = 0; i < n; i++) { indexed[i] = {arr[i], i};}sort(indexed.begin(), indexed.end());
Mistake 3: Forgetting That Sort Modifies Array
If you need the original, copy first:
vector<int> original = arr;sort(arr.begin(), arr.end());