16. Form the Largest Number

βœ… GFG solution to the Form the Largest Number problem: arrange integers to form the largest possible number using custom comparator sorting technique. πŸš€

The problem can be found at the following link: πŸ”— Question Link

🧩 Problem Description

You are given an array arr[] of non-negative integers. Your task is to arrange them so that after concatenating all of them in order, it results in the largest possible number. Since the result may be very large, return it as a string.

The key insight is that we need to sort the numbers based on which arrangement produces a larger concatenated result, not by their numerical values.

πŸ“˜ Examples

Example 1

Input: arr[] = [3, 30, 34, 5, 9]
Output: "9534330"
Explanation: Given numbers are [3, 30, 34, 5, 9], the arrangement [9, 5, 34, 3, 30] 
gives the largest value.

Example 2

Input: arr[] = [54, 546, 548, 60]
Output: "6054854654"
Explanation: Given numbers are [54, 546, 548, 60], the arrangement [60, 548, 546, 54] 
gives the largest value.

Example 3

Input: arr[] = [3, 4, 6, 5, 9]
Output: "96543"
Explanation: Given numbers are [3, 4, 6, 5, 9], the arrangement [9, 6, 5, 4, 3] 
gives the largest value.

πŸ”’ Constraints

  • $1 \le \text{arr.size()} \le 10^5$

  • $0 \le \text{arr}[i] \le 10^5$

βœ… My Approach

The optimal approach uses Custom Comparator Sorting with String Concatenation to determine the correct order:

Custom Comparator + String Sorting

  1. Convert to Strings:

    • Convert all integers to strings for easy concatenation comparison.

    • This allows us to compare concatenated results directly.

  2. Custom Comparator Logic:

    • For any two numbers a and b, compare a+b vs b+a (concatenation).

    • If a+b > b+a, then a should come before b in the final arrangement.

    • This ensures optimal ordering for maximum result.

  3. Sort with Comparator:

    • Use the custom comparator to sort the string array.

    • The comparator function: (x + y > y + x) determines order.

  4. Handle Edge Case:

    • If the largest number is "0", return "0" (handles arrays like [0, 0, 0]).

    • This prevents returning "000" instead of "0".

  5. Build Result:

    • Concatenate all sorted strings to form the final result.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n log n Γ— k), where n is the number of elements and k is the average number of digits per number. The sorting takes O(n log n) comparisons, and each comparison involves string operations that take O(k) time.

  • Expected Auxiliary Space Complexity: O(n Γ— k), where we store n strings each of average length k. The sorting algorithm may use additional O(log n) space for recursion stack.

πŸ§‘β€πŸ’» Code (C++)

class Solution {
public:
    string findLargest(vector<int>& arr) {
        vector<string> s;
        for (int x : arr) s.push_back(to_string(x));
        sort(s.begin(), s.end(), [](const string& x, const string& y) { 
            return x + y > y + x; 
        });
        if (s[0] == "0") return "0";
        string result;
        for (const string& str : s) result += str;
        return result;
    }
};
⚑ View Alternative Approaches with Code and Analysis

πŸ“Š 2️⃣ Custom Comparator with Reserve

πŸ’‘ Algorithm Steps:

  1. Pre-allocate string vector capacity to avoid reallocations.

  2. Use custom comparator function to determine optimal concatenation order.

  3. Build result string with pre-calculated capacity for better memory usage.

  4. Handle edge case of all zeros efficiently.

class Solution {
public:
    string findLargest(vector<int>& arr) {
        vector<string> nums;
        nums.reserve(arr.size());
        int totalLen = 0;
        for(int x : arr) {
            string s = to_string(x);
            nums.push_back(s);
            totalLen += s.length();
        }
        sort(nums.begin(), nums.end(), [](const string& a, const string& b) {
            return a + b > b + a;
        });
        if(nums[0] == "0") return "0";
        string result;
        result.reserve(totalLen);
        for(const string& num : nums) result += num;
        
        return result;
    }
};

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n log n Γ— k) - Where k is average digit length

  • Auxiliary Space: πŸ’Ύ O(n Γ— k) - For string vector storage

βœ… Why This Approach?

  • Memory efficient with pre-allocation

  • Reduces string reallocation overhead

  • Better cache performance

πŸ“Š 3️⃣ In-Place Integer Sorting

πŸ’‘ Algorithm Steps:

  1. Sort integers directly using custom comparison without string conversion.

  2. Convert to strings only after sorting is complete.

  3. Use integer arithmetic to compare concatenation results.

  4. Build final result string in single pass.

class Solution {
public:
    string findLargest(vector<int>& arr) {
        sort(arr.begin(), arr.end(), [](int a, int b) {
            string sa = to_string(a), sb = to_string(b);
            return sa + sb > sb + sa;
        });
        if(arr[0] == 0) return "0";
        string result;
        for(int x : arr) result += to_string(x);
        return result;
    }
};

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n log n Γ— k) - String creation during comparison

  • Auxiliary Space: πŸ’Ύ O(k) - Temporary strings in comparator

βœ… Why This Approach?

  • Works directly with original integer array

  • Minimal additional space usage

  • Clear separation of sorting and string building

πŸ“Š 4️⃣ Digit-Based Comparison

πŸ’‘ Algorithm Steps:

  1. Use mathematical approach to compare numbers without string conversion.

  2. Calculate concatenation result using digit manipulation.

  3. Compare numbers by computing actual concatenated values.

  4. Build result efficiently with minimal conversions.

class Solution {
public:
    int digitCount(int n) {
        return n == 0 ? 1 : floor(log10(n)) + 1;
    }
    string findLargest(vector<int>& arr) {
        sort(arr.begin(), arr.end(), [this](int a, int b) {
            long long ab = a * pow(10, digitCount(b)) + b;
            long long ba = b * pow(10, digitCount(a)) + a;
            return ab > ba;
        });
        if(arr[0] == 0) return "0";
        string result;
        for(int x : arr) result += to_string(x);
        return result;
    }
};

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n log n Γ— log k) - Where k is maximum number value

  • Auxiliary Space: πŸ’Ύ O(1) - No extra string storage during sort

βœ… Why This Approach?

  • Pure mathematical approach without string operations

  • Potentially faster for large numbers

  • Demonstrates algorithmic creativity

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

🏷️ Lambda Comparator + String Accumulation

🟒 O(n log n Γ— k)

🟒 O(n Γ— k)

πŸš€ Clean and readable

πŸ”§ Multiple string creations

πŸ” Reserved Memory

🟒 O(n log n Γ— k)

🟑 O(n Γ— k)

πŸ“– Memory optimized

πŸ’Ύ Complex memory management

πŸ“Š Integer Sorting

🟒 O(n log n Γ— k)

🟒 O(k)

🎯 Minimal space usage

🐌 String creation in comparator

πŸ”„ Digit Manipulation

🟑 O(n log n Γ— log k)

🟒 O(1)

⭐ Pure mathematical

πŸ”§ Complex overflow handling

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

πŸ… General purpose/Interview

πŸ₯‡ Lambda Comparator + String Accumulation

β˜…β˜…β˜…β˜…β˜…

πŸ“– Memory constrained

πŸ₯ˆ Integer Sorting

β˜…β˜…β˜…β˜…β˜†

πŸ”§ Large datasets

πŸ₯‰ Reserved Memory

β˜…β˜…β˜…β˜…β˜†

🎯 Academic/Research

πŸ… Digit Manipulation

β˜…β˜…β˜…β˜†β˜†

β˜• Code (Java)

class Solution {
    public String findLargest(int[] arr) {
        String[] s = new String[arr.length];
        for (int i = 0; i < arr.length; i++) s[i] = String.valueOf(arr[i]);
        Arrays.sort(s, (x, y) -> (x + y).compareTo(y + x) > 0 ? -1 : 1); 
        if (s[0].equals("0")) return "0";
        StringBuilder res = new StringBuilder();
        Arrays.stream(s).forEach(res::append);
        return res.toString();
    }
}

🐍 Code (Python)

class Solution:
    def findLargest(self, arr):
        s = sorted(map(str, arr), key=cmp_to_key(lambda x, y: -1 if x + y > y + x else 1))
        return '0' if s[0] == '0' else ''.join(s)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated