3309. Maximum Possible Number by Binary Concatenation
Problem Description
You have an array nums
containing exactly 3 integers.
Your task is to find the maximum possible number that can be created by:
- Converting each integer in
nums
to its binary representation (without leading zeros) - Concatenating these binary representations in some order
- Converting the resulting binary string back to a decimal number
For example, if you have numbers like 1, 2, and 3:
- 1 in binary is
"1"
- 2 in binary is
"10"
- 3 in binary is
"11"
You can arrange these binary strings in different orders like "11011"
(from 1,10,11) or "11110"
(from 11,1,10) or "10111"
(from 10,1,11), etc. Each arrangement gives a different decimal value when converted back.
The solution works by trying all 6 possible permutations of the 3 numbers (since 3! = 6). For each permutation:
- Convert each number to its binary string using
bin(i)[2:]
(the[2:]
removes the '0b' prefix) - Join all binary strings together
- Convert the concatenated binary string to decimal using
int(..., 2)
- Track the maximum value found
The function returns the largest decimal number that can be formed through any arrangement of the binary representations.
Intuition
When we concatenate binary strings, we want the resulting binary number to be as large as possible. In binary, a number is larger when it has more significant bits set to 1 in the leftmost positions.
Since we're dealing with only 3 numbers, the brute force approach becomes feasible. With just 3 elements, there are only 3! = 6
possible arrangements to check. This small number of possibilities makes it practical to simply try all permutations and pick the maximum.
The key insight is that the optimal ordering isn't immediately obvious from just looking at the decimal values. For instance, if we have numbers 2 ("10"
), 8 ("1000"
), and 10 ("1010"
), the arrangement that produces the maximum isn't necessarily in descending order of the original numbers. We need to consider how the binary representations concatenate together.
When we concatenate "10"
+ "1000"
we get "101000"
(which is 40 in decimal), but if we concatenate "1000"
+ "10"
we get "100010"
(which is 34 in decimal). The first arrangement is better even though we put the smaller number first.
Since determining the optimal order requires considering the actual binary concatenations and there's no simple rule to determine the best order without trying the combinations, the most straightforward approach is to generate all permutations, compute the resulting decimal value for each, and return the maximum. The small fixed size of the input (always 3 elements) makes this exhaustive search both simple and efficient.
Solution Approach
The solution uses a brute force enumeration approach with Python's permutations
function from the itertools
module.
Step-by-step implementation:
-
Initialize the maximum value: Start with
ans = 0
to track the maximum decimal number found. -
Generate all permutations: Use
permutations(nums)
to generate all 6 possible orderings of the 3 numbers. For example, ifnums = [1, 2, 3]
, it generates:(1, 2, 3)
,(1, 3, 2)
,(2, 1, 3)
,(2, 3, 1)
,(3, 1, 2)
,(3, 2, 1)
-
Process each permutation: For each arrangement
arr
:- Convert each number to binary using
bin(i)[2:]
bin(i)
returns a string like"0b101"
[2:]
slices off the"0b"
prefix, leaving just"101"
- Join all binary strings together using
"".join(...)
- Convert the concatenated binary string to decimal using
int(..., 2)
where the second parameter2
indicates base-2 (binary)
- Convert each number to binary using
-
Track the maximum: Compare each resulting decimal number with the current maximum using
ans = max(ans, num)
. -
Return the result: After checking all permutations, return the maximum value found.
Example walkthrough:
If nums = [1, 2, 3]
:
- Permutation
(1, 2, 3)
:"1"
+"10"
+"11"
="11011"
→ 27 in decimal - Permutation
(3, 2, 1)
:"11"
+"10"
+"1"
="11101"
→ 29 in decimal - And so on for all 6 permutations...
The algorithm would return 30, which comes from the arrangement that produces "11110"
in binary.
The time complexity is O(1)
since we always have exactly 3 elements and 6 permutations to check. The space complexity is also O(1)
as we only store a fixed amount of data regardless of the input values.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with nums = [2, 8, 10]
:
Step 1: Convert each number to binary
- 2 →
"10"
- 8 →
"1000"
- 10 →
"1010"
Step 2: Try all 6 permutations and calculate their decimal values
-
(2, 8, 10):
"10"
+"1000"
+"1010"
="1010001010"
- Converting
"1010001010"
to decimal: 650
- Converting
-
(2, 10, 8):
"10"
+"1010"
+"1000"
="1010101000"
- Converting
"1010101000"
to decimal: 680
- Converting
-
(8, 2, 10):
"1000"
+"10"
+"1010"
="1000101010"
- Converting
"1000101010"
to decimal: 554
- Converting
-
(8, 10, 2):
"1000"
+"1010"
+"10"
="100010101"0
- Converting
"10001010010"
to decimal: 1106
- Converting
-
(10, 2, 8):
"1010"
+"10"
+"1000"
="1010101000"
- Converting
"1010101000"
to decimal: 680
- Converting
-
(10, 8, 2):
"1010"
+"1000"
+"10"
="101010001"0
- Converting
"10101000010"
to decimal: 1346
- Converting
Step 3: Find the maximum Comparing all results: 650, 680, 554, 1106, 680, 1346
The maximum value is 1346, which comes from the arrangement (10, 8, 2).
This demonstrates why we need to check all permutations - the optimal order isn't intuitive and doesn't follow the original decimal ordering of the numbers.
Solution Implementation
1from typing import List
2from itertools import permutations
3
4class Solution:
5 def maxGoodNumber(self, nums: List[int]) -> int:
6 """
7 Find the maximum number that can be formed by concatenating
8 the binary representations of the numbers in different orders.
9
10 Args:
11 nums: List of integers to concatenate in binary form
12
13 Returns:
14 Maximum possible integer value after binary concatenation
15 """
16 max_value = 0
17
18 # Try all possible permutations of the input numbers
19 for permutation in permutations(nums):
20 # Convert each number to binary (removing '0b' prefix)
21 # and concatenate them
22 binary_string = "".join(bin(num)[2:] for num in permutation)
23
24 # Convert the concatenated binary string back to decimal
25 decimal_value = int(binary_string, 2)
26
27 # Update maximum value found so far
28 max_value = max(max_value, decimal_value)
29
30 return max_value
31
1class Solution {
2 // Array to store input numbers
3 private int[] nums;
4
5 /**
6 * Finds the maximum number that can be formed by concatenating
7 * the binary representations of three numbers in any order.
8 *
9 * @param nums Array containing exactly 3 integers
10 * @return The maximum decimal value formed by binary concatenation
11 */
12 public int maxGoodNumber(int[] nums) {
13 // Store the input array in instance variable
14 this.nums = nums;
15
16 // Try all 6 possible permutations of 3 numbers (3! = 6)
17 // and find the maximum value
18 int maxValue = f(0, 1, 2); // Permutation: nums[0], nums[1], nums[2]
19 maxValue = Math.max(maxValue, f(0, 2, 1)); // Permutation: nums[0], nums[2], nums[1]
20 maxValue = Math.max(maxValue, f(1, 0, 2)); // Permutation: nums[1], nums[0], nums[2]
21 maxValue = Math.max(maxValue, f(1, 2, 0)); // Permutation: nums[1], nums[2], nums[0]
22 maxValue = Math.max(maxValue, f(2, 0, 1)); // Permutation: nums[2], nums[0], nums[1]
23 maxValue = Math.max(maxValue, f(2, 1, 0)); // Permutation: nums[2], nums[1], nums[0]
24
25 return maxValue;
26 }
27
28 /**
29 * Helper method to concatenate binary representations of three numbers
30 * and convert the result back to decimal.
31 *
32 * @param i Index of first number in nums array
33 * @param j Index of second number in nums array
34 * @param k Index of third number in nums array
35 * @return Decimal value of concatenated binary strings
36 */
37 private int f(int i, int j, int k) {
38 // Convert each number to its binary string representation
39 String firstBinary = Integer.toBinaryString(nums[i]);
40 String secondBinary = Integer.toBinaryString(nums[j]);
41 String thirdBinary = Integer.toBinaryString(nums[k]);
42
43 // Concatenate the binary strings and parse as binary to get decimal value
44 String concatenatedBinary = firstBinary + secondBinary + thirdBinary;
45 return Integer.parseInt(concatenatedBinary, 2);
46 }
47}
48
1class Solution {
2public:
3 int maxGoodNumber(vector<int>& nums) {
4 int maxResult = 0;
5
6 // Lambda function to convert array of numbers to a single integer
7 // by concatenating their binary representations
8 auto concatenateBinary = [&](vector<int>& nums) {
9 int result = 0;
10 vector<int> binaryDigits;
11
12 // Extract all binary digits from each number in the array
13 for (int num : nums) {
14 // Convert each number to binary and store digits in reverse order
15 while (num > 0) {
16 binaryDigits.push_back(num & 1); // Get least significant bit
17 num >>= 1; // Right shift to process next bit
18 }
19 }
20
21 // Reconstruct the number from binary digits (stored in reverse)
22 while (!binaryDigits.empty()) {
23 result = result * 2 + binaryDigits.back(); // Build number from MSB to LSB
24 binaryDigits.pop_back();
25 }
26
27 return result;
28 };
29
30 // Try all possible permutations of the array (3! = 6 permutations for 3 elements)
31 for (int i = 0; i < 6; ++i) {
32 // Calculate the concatenated binary value for current permutation
33 maxResult = max(maxResult, concatenateBinary(nums));
34 // Generate next permutation
35 next_permutation(nums.begin(), nums.end());
36 }
37
38 return maxResult;
39 }
40};
41
1/**
2 * Finds the maximum number that can be formed by concatenating
3 * the binary representations of three numbers in any order
4 * @param nums - Array containing exactly 3 numbers
5 * @returns The maximum decimal value after binary concatenation
6 */
7function maxGoodNumber(nums: number[]): number {
8 /**
9 * Concatenates binary representations of three numbers at given indices
10 * and converts the result back to decimal
11 * @param firstIndex - Index of the first number
12 * @param secondIndex - Index of the second number
13 * @param thirdIndex - Index of the third number
14 * @returns Decimal value of concatenated binary strings
15 */
16 const concatenateBinaryNumbers = (
17 firstIndex: number,
18 secondIndex: number,
19 thirdIndex: number
20 ): number => {
21 // Convert each number to its binary string representation
22 const firstBinary: string = nums[firstIndex].toString(2);
23 const secondBinary: string = nums[secondIndex].toString(2);
24 const thirdBinary: string = nums[thirdIndex].toString(2);
25
26 // Concatenate binary strings and convert back to decimal
27 const concatenatedBinary: string = firstBinary + secondBinary + thirdBinary;
28 const decimalResult: number = parseInt(concatenatedBinary, 2);
29
30 return decimalResult;
31 };
32
33 // Try all 6 possible permutations of the 3 numbers
34 let maximumValue: number = concatenateBinaryNumbers(0, 1, 2);
35 maximumValue = Math.max(maximumValue, concatenateBinaryNumbers(0, 2, 1));
36 maximumValue = Math.max(maximumValue, concatenateBinaryNumbers(1, 0, 2));
37 maximumValue = Math.max(maximumValue, concatenateBinaryNumbers(1, 2, 0));
38 maximumValue = Math.max(maximumValue, concatenateBinaryNumbers(2, 0, 1));
39 maximumValue = Math.max(maximumValue, concatenateBinaryNumbers(2, 1, 0));
40
41 return maximumValue;
42}
43
Time and Space Complexity
The time complexity is O(n! × n × log M)
, where n
is the length of the nums
array (which is 3 based on the problem context) and M
represents the maximum value of the elements in nums
. Breaking this down:
permutations(nums)
generatesn!
permutations- For each permutation, we iterate through
n
elements to build the binary string - Converting each number to binary using
bin(i)[2:]
takesO(log M)
time - The
int(..., 2)
conversion also takesO(n × log M)
time for the concatenated binary string
Since n = 3
is a constant, the time complexity simplifies to O(log M)
.
The space complexity is O(n × log M)
for storing the concatenated binary string during each iteration. However, since n = 3
is constant and we're not storing all permutations simultaneously, the space complexity simplifies to O(log M)
. If we consider only the extra space beyond the input, it can be considered O(1)
when treating the maximum binary representation length as a constant factor.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. String Concatenation Order Confusion
A common mistake is assuming that lexicographically larger binary strings will always produce larger decimal values when concatenated. This isn't true because the position of bits matters significantly in the final decimal value.
Incorrect Assumption:
# Wrong: Trying to sort binary strings lexicographically
def maxGoodNumber(self, nums: List[int]) -> int:
binaries = [bin(num)[2:] for num in nums]
binaries.sort(reverse=True) # This doesn't guarantee maximum decimal
return int("".join(binaries), 2)
Why it fails: Consider nums = [1, 2, 3]
:
- Sorting binary strings:
["11", "10", "1"]
→"11101"
= 29 - But
["11", "1", "10"]
→"11110"
= 30 (which is larger!)
2. Custom Comparator Pitfall
Another flawed approach is using a custom comparator to sort numbers based on their concatenated binary values:
Incorrect Implementation:
# Wrong: Simple comparison of concatenated pairs
def maxGoodNumber(self, nums: List[int]) -> int:
nums.sort(key=lambda x: bin(x)[2:], reverse=True)
binary = "".join(bin(num)[2:] for num in nums)
return int(binary, 2)
Correct Approach with Custom Comparator:
from functools import cmp_to_key
def maxGoodNumber(self, nums: List[int]) -> int:
def compare(x, y):
# Compare which order produces a larger binary number
bin_x, bin_y = bin(x)[2:], bin(y)[2:]
if bin_x + bin_y > bin_y + bin_x:
return -1 # x should come before y
elif bin_x + bin_y < bin_y + bin_x:
return 1 # y should come before x
else:
return 0 # order doesn't matter
nums.sort(key=cmp_to_key(compare))
binary_string = "".join(bin(num)[2:] for num in nums)
return int(binary_string, 2)
3. Overlooking Edge Cases with Zero
If the array contains 0, its binary representation is just "0"
, which acts as padding when placed in the middle or beginning:
Example: nums = [0, 1, 2]
[1, 2, 0]
→"1"
+"10"
+"0"
="1100"
= 12[2, 1, 0]
→"10"
+"1"
+"0"
="1010"
= 10- Always place zeros at the end for maximum value!
4. Integer Overflow Concerns
While Python handles arbitrary precision integers automatically, in other languages you might encounter overflow:
Prevention Strategy:
- Check the maximum possible binary string length: with 3 numbers each up to 10^9, the binary representation can be quite long
- In languages like Java or C++, use appropriate data types (
long long
in C++,Long
in Java) - Consider using string comparison if the result might exceed integer limits
Example validation:
def maxGoodNumber(self, nums: List[int]) -> int:
max_value = 0
for permutation in permutations(nums):
binary_string = "".join(bin(num)[2:] for num in permutation)
# Optional: Check for potential overflow in other languages
if len(binary_string) > 64: # Would overflow in 64-bit systems
# Handle appropriately based on requirements
pass
decimal_value = int(binary_string, 2)
max_value = max(max_value, decimal_value)
return max_value
A person thinks of a number between 1 and 1000. You may ask any number questions to them, provided that the question can be answered with either "yes" or "no".
What is the minimum number of questions you needed to ask so that you are guaranteed to know the number that the person is thinking?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!