Given an array of non-negative integers, arrange them such that after concatenating all of them together, it forms the largest possible number.
Since the number can be very large, we must return the answer as a string.
- 1 ≤ arr.size() ≤ 10^5
- 0 ≤ arr[i] ≤ 10^5
- Expected Time Complexity: O(n log n)
- Expected Auxiliary Space: O(n)
When I first looked at this problem, I thought I could just sort the numbers in descending order and join them.
But that does not always work.
For example: 3 and 30
If I sort normally in descending order → 30, 3 → 303 But if I arrange → 3, 30 → 330 which is bigger.
So I realized that normal numeric sorting is not correct.
Then I thought differently. Instead of comparing numbers directly, what if I compare them after concatenating?
For two numbers a and b, I compare:
- a + b
- b + a
Whichever gives the larger result should come first.
That simple idea solves the entire problem.
-
Convert all integers into strings.
-
Sort them using a custom comparator.
-
In comparator:
- If a + b > b + a, then a comes first.
-
After sorting, join all strings.
-
Handle edge case:
- If the first element is "0", return "0".
- Array / Vector
- String array
- Custom comparator in sorting
No complex data structures are required.
- Convert integers to strings.
- Apply custom sorting logic.
- Concatenate sorted strings.
- Handle edge case for multiple zeros.
Time Complexity: O(n log n)
- Sorting n elements takes O(n log n).
- Each comparison involves string concatenation of small numbers.
Space Complexity: O(n)
- We store numbers as strings.
- Sorting may use extra internal memory.
class Solution {
public:
static bool compare(string a, string b) {
return a + b > b + a;
}
string findLargest(vector<int> &arr) {
vector<string> nums;
for(int num : arr) {
nums.push_back(to_string(num));
}
sort(nums.begin(), nums.end(), compare);
if(nums[0] == "0") return "0";
string result = "";
for(string s : nums) {
result += s;
}
return result;
}
};import java.util.*;
class Solution {
public String findLargest(int[] arr) {
String[] nums = new String[arr.length];
for(int i = 0; i < arr.length; i++) {
nums[i] = String.valueOf(arr[i]);
}
Arrays.sort(nums, (a, b) -> (b + a).compareTo(a + b));
if(nums[0].equals("0")) return "0";
StringBuilder sb = new StringBuilder();
for(String s : nums) {
sb.append(s);
}
return sb.toString();
}
}class Solution {
findLargest(arr) {
let nums = arr.map(num => num.toString());
nums.sort((a, b) => (b + a).localeCompare(a + b));
if(nums[0] === "0") return "0";
return nums.join("");
}
}from functools import cmp_to_key
class Solution:
def compare(self, a, b):
if a + b > b + a:
return -1
elif a + b < b + a:
return 1
else:
return 0
def findLargest(self, arr):
nums = list(map(str, arr))
nums.sort(key=cmp_to_key(self.compare))
if nums[0] == "0":
return "0"
return "".join(nums)We convert every number into string because we need concatenation comparison.
For two strings a and b:
- Compare a + b
- Compare b + a
If a + b is larger, place a first.
Example: For 54 and 546: 54546 54654
Since 54654 is larger, 546 comes first.
If all elements are zero: Example: [0, 0, 0] After sorting → ["0", "0", "0"] We return "0" instead of "000".
Finally, join all sorted strings to form the largest number.
Input: [3, 30, 34, 5, 9] Output: 9534330
Input: [54, 546, 548, 60] Output: 6054854654
Input: [3, 4, 6, 5, 9] Output: 96543
Compile using:
g++ filename.cpp -o output
./outputjavac Solution.java
java Solutionnode filename.jspython3 filename.py- Do not sort normally by numeric value.
- Always use string concatenation comparison.
- Handle zero edge case carefully.
- Sorting dominates the time complexity.