LeetCode 3309 - Maximum Possible Number by Binary Concatenation
The problem is asking for the maximum integer value that can be created by concatenating the binary representations of all elements in a list of three integers. Each number should be converted to its binary representation without leading zeros.
Difficulty: 🟡 Medium
Topics: Array, Bit Manipulation, Enumeration
Solution
Problem Understanding
The problem is asking for the maximum integer value that can be created by concatenating the binary representations of all elements in a list of three integers. Each number should be converted to its binary representation without leading zeros. After conversion, the binary strings can be concatenated in any order. The resulting binary string should then be interpreted as a decimal integer, which is the final output.
The input nums is guaranteed to have exactly three integers, each between 1 and 127. This ensures that each binary representation fits within 7 bits, and there will never be any leading zeros in the binary conversion.
The output is a single integer that is the maximum possible value formed by any ordering of the binary strings. Edge cases include numbers that have binary representations of different lengths, as the position of longer binary strings can disproportionately increase the final integer value.
Approaches
The brute-force approach involves generating all possible permutations of the three integers, converting each to binary, concatenating them, and then converting the concatenation back to an integer. This guarantees correctness because it exhaustively checks all orderings, but it is unnecessary for such a small fixed input because there is a mathematical way to choose the "largest" concatenation directly.
The key insight for an optimal solution is that the ordering of binary strings is similar to string sorting for maximum concatenation, where for any two binary strings a and b, placing a before b is better if a+b is lexicographically larger than b+a. This reduces the problem to a sort based on a custom comparison, which is very efficient given the small array size.
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(3!) = O(6) | O(1) | Check all permutations of the 3 elements |
| Optimal | O(n log n) = O(3 log 3) = O(1) | O(n) = O(3) | Sort using custom comparison of concatenated binary strings |
Algorithm Walkthrough
- Convert each integer in the array to its binary representation without leading zeros.
- Define a comparison rule for two binary strings
aandb:ashould come beforebif the concatenationa+bis greater thanb+awhen interpreted lexicographically. - Sort the list of binary strings using this comparison.
- Concatenate the sorted binary strings into a single binary string.
- Convert the final binary string to an integer using base 2.
- Return this integer as the result.
Why it works: Sorting the binary strings by the a+b > b+a rule guarantees that the largest possible binary string is formed. This is similar to the "largest number from array" problem, but using binary representations instead of decimal strings.
Python Solution
from typing import List
class Solution:
def maxGoodNumber(self, nums: List[int]) -> int:
# Step 1: Convert integers to binary strings
binaries = [bin(num)[2:] for num in nums]
# Step 2: Sort with custom comparator
binaries.sort(key=lambda x: x*7, reverse=True)
# Step 3: Concatenate sorted binaries
result_binary = ''.join(binaries)
# Step 4: Convert binary string to integer
return int(result_binary, 2)
The code converts each number to a binary string using bin(num)[2:] to remove the '0b' prefix. It sorts the strings with a lambda key that multiplies the string to ensure proper lexicographical comparison. The sorted strings are concatenated, and int(result_binary, 2) converts the binary string to the final integer.
Go Solution
import (
"sort"
"strconv"
)
func maxGoodNumber(nums []int) int {
binaries := make([]string, len(nums))
for i, num := range nums {
binaries[i] = strconv.FormatInt(int64(num), 2)
}
sort.Slice(binaries, func(i, j int) bool {
return binaries[i]+binaries[j] > binaries[j]+binaries[i]
})
resultBinary := ""
for _, b := range binaries {
resultBinary += b
}
result, _ := strconv.ParseInt(resultBinary, 2, 64)
return int(result)
}
In Go, strconv.FormatInt converts integers to binary strings. The slice is sorted using a custom comparison function. The final binary string is concatenated and converted to an integer using strconv.ParseInt. Go requires explicit 64-bit integer parsing, but this is safe given the maximum possible length of the binary string.
Worked Examples
Example 1: nums = [1, 2, 3]
- Convert to binaries:
[1, 10, 11] - Compare concatenations:
11+1+10 = "11110"> any other order - Resulting binary string:
"11110" - Convert to integer:
30
Example 2: nums = [2, 8, 16]
- Convert to binaries:
[10, 1000, 10000] - Compare concatenations:
"10000100010"(from[16, 8, 2]) - Convert to integer:
1296
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n log n) | Sorting three elements, effectively constant |
| Space | O(n) | Store binary strings for concatenation |
The complexity is dominated by the sorting operation, which is trivial for n = 3. The space complexity is proportional to storing the binary strings, also very small.
Test Cases
# Provided examples
assert Solution().maxGoodNumber([1,2,3]) == 30 # "11110"
assert Solution().maxGoodNumber([2,8,16]) == 1296 # "10100010000"
# Edge cases
assert Solution().maxGoodNumber([1,1,1]) == 7 # "111"
assert Solution().maxGoodNumber([127,1,2]) == 32639 # "1111111" + "10" + "1"
assert Solution().maxGoodNumber([5,10,15]) == 13375 # "1111" + "1010" + "101"
| Test | Why |
|---|---|
| [1,2,3] | Basic small integers, checks ordering of different binary lengths |
| [2,8,16] | Powers of two, checks handling of different lengths |
| [1,1,1] | All numbers equal, ensures code handles identical binaries |
| [127,1,2] | Maximum allowed number, tests large binary string |
| [5,10,15] | Mixed small numbers, tests correct binary concatenation ordering |
Edge Cases
One important edge case is when all numbers are identical, such as [1,1,1]. A naive implementation that assumes unique numbers might fail, but this algorithm correctly concatenates identical binaries in any order, giving the correct result.
Another edge case is when one number is significantly larger than the others, like [127,1,2]. Its binary representation is much longer, so it must appear first in the concatenation to maximize the result. The sorting ensures this automatically.
A final edge case involves numbers whose binary strings have similar prefixes, such as [5,10,15]. Without careful comparison, a lexicographical sort could choose the wrong order. By explicitly comparing a+b vs b+a, the algorithm ensures the optimal ordering even in tricky prefix scenarios.