Facebook Pixel

3602. Hexadecimal and Hexatrigesimal Conversion

Problem Description

You are given an integer n. Your task is to:

  1. Calculate (n squared) and convert it to hexadecimal (base-16)
  2. Calculate (n cubed) and convert it to hexatrigesimal (base-36)
  3. Concatenate these two string representations and return the result

Number System Details:

  • Hexadecimal (base-16): Uses digits 0-9 and uppercase letters A-F to represent values 0 to 15

    • For example: 10 in decimal = A in hexadecimal, 15 in decimal = F in hexadecimal
  • Hexatrigesimal (base-36): Uses digits 0-9 and uppercase letters A-Z to represent values 0 to 35

    • For example: 10 in decimal = A in base-36, 35 in decimal = Z in base-36

Example walkthrough:

If n = 4:

  • n² = 16 → hexadecimal representation is "10"
  • n³ = 64 → base-36 representation is "1S" (since 64 = 1×36 + 28, and 28 is represented as 'S')
  • Result: "10" + "1S" = "101S"

The solution implements a helper function f(x, k) that converts any integer x to its representation in base k. It works by:

  1. Repeatedly finding the remainder when dividing by the base
  2. Converting each remainder to its appropriate character (digit or letter)
  3. Building the result string from least significant to most significant digit
  4. Reversing the result to get the correct order

The main function then applies this conversion to with base 16 and with base 36, concatenating the results.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The core challenge here is converting numbers to different base systems. When we think about how number systems work, any number in base k can be broken down into powers of k.

For example, the number 234 in base 10 means: 2×10² + 3×10¹ + 4×10⁰

To convert a decimal number to any base, we can use the division method:

  • Divide the number by the base and keep track of the remainder
  • The remainder gives us the rightmost digit in the new base
  • Continue with the quotient until it becomes 0
  • The remainders, read in reverse order, give us the number in the new base

Let's trace through converting 16 to hexadecimal (base 16):

  • 16 ÷ 16 = 1 remainder 0
  • 1 ÷ 16 = 0 remainder 1
  • Reading remainders in reverse: "10"

The tricky part is handling bases larger than 10, where we need letters. When the remainder is 10 or more:

  • In hexadecimal: 10→A, 11→B, ..., 15→F
  • In base-36: 10→A, 11→B, ..., 35→Z

This mapping can be achieved using ASCII values: if remainder v > 9, we use chr(ord('A') + v - 10) to get the corresponding letter.

Since both conversions follow the same pattern (just with different bases), we can create a single function f(x, k) that handles any base conversion. This avoids code duplication and makes the solution cleaner.

The final step is straightforward: compute and , convert them using our function with the appropriate bases (16 and 36), and concatenate the results.

Learn more about Math patterns.

Solution Approach

The solution implements a simulation approach with a helper function for base conversion.

Helper Function f(x, k) - Base Conversion Algorithm:

The function converts an integer x to its string representation in base k:

  1. Initialize an empty list res to store the digits/characters in reverse order
  2. Extract digits using modulo operation:
    • While x > 0:
      • Calculate remainder: v = x % k
      • If v <= 9: append the digit as a string str(v)
      • If v > 9: convert to letter using chr(ord("A") + v - 10)
        • This maps 10→'A', 11→'B', and so on
      • Update x by integer division: x //= k
  3. Reverse and join the result: "".join(res[::-1])
    • We reverse because we built the number from least to most significant digit

Main Function Flow:

  1. Calculate the powers:

    • x = n ** 2 (n squared)
    • y = n ** 3 (n cubed)
  2. Convert to respective bases:

    • Convert x to hexadecimal: f(x, 16)
    • Convert y to base-36: f(y, 36)
  3. Concatenate and return: Simply concatenate the two strings

Example Trace for n = 4:

  • x = 16, y = 64
  • Converting 16 to hex (base 16):
    • 16 % 16 = 0 → append '0'
    • 16 // 16 = 1
    • 1 % 16 = 1 → append '1'
    • 1 // 16 = 0 → stop
    • Reverse: "10"
  • Converting 64 to base-36:
    • 64 % 36 = 2828 > 9, so append chr(65 + 28 - 10) = chr(83) = 'S'
    • 64 // 36 = 1
    • 1 % 36 = 1 → append '1'
    • 1 // 36 = 0 → stop
    • Reverse: "1S"
  • Result: "10" + "1S" = "101S"

The time complexity is O(log x + log y) where x = n² and y = n³, as we process each digit once. The space complexity is also O(log x + log y) for storing the result strings.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with n = 12:

Step 1: Calculate the powers

  • n² = 12² = 144
  • n³ = 12³ = 1728

Step 2: Convert 144 to hexadecimal (base-16)

Using the division method with our helper function f(144, 16):

  • 144 ÷ 16 = 9 remainder 0 → append '0'
  • 9 ÷ 16 = 0 remainder 9 → append '9'
  • Stop (quotient is 0)
  • Reverse the digits: "90"

Step 3: Convert 1728 to base-36

Using our helper function f(1728, 36):

  • 1728 ÷ 36 = 48 remainder 0 → append '0'
  • 48 ÷ 36 = 1 remainder 12 → Since 12 > 9, convert to letter: chr(65 + 12 - 10) = chr(67) = 'C' → append 'C'
  • 1 ÷ 36 = 0 remainder 1 → append '1'
  • Stop (quotient is 0)
  • Reverse the characters: "1C0"

Step 4: Concatenate the results

  • Hexadecimal of 144: "90"
  • Base-36 of 1728: "1C0"
  • Final result: "90" + "1C0" = "901C0"

The key insight is that both conversions follow the same pattern - we repeatedly divide by the base and collect remainders, converting values above 9 to letters. By implementing this once in the helper function f(x, k), we can handle both base-16 and base-36 conversions efficiently.

Solution Implementation

1class Solution:
2    def concatHex36(self, n: int) -> str:
3        """
4        Concatenates the hexadecimal representation of n^2 with 
5        the base-36 representation of n^3.
6      
7        Args:
8            n: An integer input value
9          
10        Returns:
11            A string containing hex(n^2) + base36(n^3)
12        """
13      
14        def convert_to_base(number: int, base: int) -> str:
15            """
16            Converts a decimal number to a specified base (up to base 36).
17          
18            Args:
19                number: The decimal number to convert
20                base: The target base (2-36)
21              
22            Returns:
23                String representation of the number in the specified base
24            """
25            # Handle edge case of 0
26            if number == 0:
27                return "0"
28          
29            result = []
30          
31            # Convert number to target base by repeatedly dividing
32            while number > 0:
33                remainder = number % base
34              
35                # For digits 0-9, use the digit itself
36                if remainder <= 9:
37                    result.append(str(remainder))
38                # For digits 10-35, use letters A-Z
39                else:
40                    result.append(chr(ord('A') + remainder - 10))
41              
42                # Integer division to get next digit
43                number //= base
44          
45            # Reverse the result since we built it backwards
46            return ''.join(result[::-1])
47      
48        # Calculate n squared and n cubed
49        n_squared = n ** 2
50        n_cubed = n ** 3
51      
52        # Convert n^2 to hexadecimal (base 16) and n^3 to base 36
53        hex_representation = convert_to_base(n_squared, 16)
54        base36_representation = convert_to_base(n_cubed, 36)
55      
56        # Concatenate and return the two representations
57        return hex_representation + base36_representation
58
1class Solution {
2    /**
3     * Concatenates the hexadecimal representation of n^2 and 
4     * the base-36 representation of n^3.
5     * 
6     * @param n the input integer
7     * @return concatenated string of n^2 in base-16 and n^3 in base-36
8     */
9    public String concatHex36(int n) {
10        int nSquared = n * n;
11        int nCubed = n * n * n;
12      
13        // Convert n^2 to hexadecimal (base-16) and n^3 to base-36
14        return convertToBase(nSquared, 16) + convertToBase(nCubed, 36);
15    }
16
17    /**
18     * Converts a decimal number to a string representation in the specified base.
19     * Supports bases from 2 to 36, where digits 0-9 represent values 0-9
20     * and letters A-Z represent values 10-35.
21     * 
22     * @param decimalNumber the decimal number to convert
23     * @param base the target base (should be between 2 and 36)
24     * @return string representation of the number in the specified base
25     */
26    private String convertToBase(int decimalNumber, int base) {
27        StringBuilder result = new StringBuilder();
28      
29        // Handle edge case where input is 0
30        if (decimalNumber == 0) {
31            return "0";
32        }
33      
34        // Extract digits from least significant to most significant
35        while (decimalNumber > 0) {
36            int remainder = decimalNumber % base;
37          
38            if (remainder <= 9) {
39                // For values 0-9, use numeric characters
40                result.append((char) ('0' + remainder));
41            } else {
42                // For values 10-35, use alphabetic characters A-Z
43                result.append((char) ('A' + remainder - 10));
44            }
45          
46            decimalNumber /= base;
47        }
48      
49        // Reverse the string since we built it from least to most significant digit
50        return result.reverse().toString();
51    }
52}
53
1class Solution {
2public:
3    /**
4     * Concatenates n² in hexadecimal and n³ in base-36
5     * @param n: The input integer
6     * @return: A string containing n² in hex followed by n³ in base-36
7     */
8    string concatHex36(int n) {
9        int square = n * n;
10        int cube = n * n * n;
11      
12        // Convert n² to hexadecimal (base 16) and n³ to base-36
13        return convertToBase(square, 16) + convertToBase(cube, 36);
14    }
15
16private:
17    /**
18     * Converts a decimal number to a string representation in the specified base
19     * @param number: The decimal number to convert
20     * @param base: The target base (supports up to base-36)
21     * @return: String representation of the number in the specified base
22     */
23    string convertToBase(int number, int base) {
24        string result;
25      
26        // Handle each digit from least significant to most significant
27        while (number > 0) {
28            int remainder = number % base;
29          
30            // For digits 0-9, use characters '0'-'9'
31            if (remainder <= 9) {
32                result += char('0' + remainder);
33            } 
34            // For digits 10-35, use characters 'A'-'Z'
35            else {
36                result += char('A' + remainder - 10);
37            }
38          
39            number /= base;
40        }
41      
42        // Reverse the string since we built it backwards
43        reverse(result.begin(), result.end());
44      
45        return result;
46    }
47};
48
1/**
2 * Concatenates hexadecimal representation of n² and base-36 representation of n³
3 * @param n - The input number
4 * @returns A string concatenation of n² in base-16 and n³ in base-36
5 */
6function concatHex36(n: number): string {
7    /**
8     * Converts a decimal number to a string representation in the specified base
9     * @param decimalNumber - The decimal number to convert
10     * @param base - The target base (between 2 and 36)
11     * @returns String representation of the number in the specified base
12     */
13    function convertToBase(decimalNumber: number, base: number): string {
14        // Character set for digits 0-9 and letters A-Z (supports up to base-36)
15        const DIGIT_CHARACTERS: string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
16      
17        let result: string = '';
18      
19        // Convert decimal to target base by repeatedly dividing and taking remainders
20        while (decimalNumber > 0) {
21            const remainder: number = decimalNumber % base;
22            // Prepend the corresponding character to build the result from right to left
23            result = DIGIT_CHARACTERS[remainder] + result;
24            decimalNumber = Math.floor(decimalNumber / base);
25        }
26      
27        return result;
28    }
29
30    // Calculate n squared
31    const nSquared: number = n * n;
32  
33    // Calculate n cubed
34    const nCubed: number = n * n * n;
35  
36    // Convert n² to hexadecimal (base-16) and n³ to base-36, then concatenate
37    return convertToBase(nSquared, 16) + convertToBase(nCubed, 36);
38}
39

Time and Space Complexity

The time complexity is O(log n). This is because:

  • Computing and takes constant time
  • The function f(x, k) performs divisions by base k until x becomes 0
  • For f(n², 16): The number of iterations is O(log₁₆(n²)) = O(2 * log₁₆(n)) = O(log n)
  • For f(n³, 36): The number of iterations is O(log₃₆(n³)) = O(3 * log₃₆(n)) = O(log n)
  • Since both conversions are O(log n) and they run sequentially, the overall time complexity is O(log n)

The space complexity is O(log n), not O(1) as stated in the reference answer. This is because:

  • The res list in function f stores the digits of the number in the target base
  • For in base 16, we need O(log₁₆(n²)) = O(log n) digits
  • For in base 36, we need O(log₃₆(n³)) = O(log n) digits
  • The final string concatenation also requires O(log n) space for the result
  • Therefore, the space complexity is O(log n)

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Forgetting to Handle Zero Edge Case

The most common pitfall is not properly handling when n = 0. Without a special check, the base conversion function would return an empty string since the while loop condition number > 0 would never execute.

Problem Code:

def convert_to_base(number: int, base: int) -> str:
    result = []
    while number > 0:  # This loop never runs when number = 0
        remainder = number % base
        # ... conversion logic
        number //= base
    return ''.join(result[::-1])  # Returns "" for number = 0

Solution: Add an explicit check at the beginning of the conversion function:

def convert_to_base(number: int, base: int) -> str:
    if number == 0:
        return "0"
    # ... rest of the conversion logic

2. Using Lowercase Letters Instead of Uppercase

The problem specifically requires uppercase letters (A-Z) for digits above 9. A common mistake is using lowercase letters or forgetting to specify the case.

Problem Code:

# Wrong: produces lowercase letters
result.append(chr(ord('a') + remainder - 10))

Solution: Always use uppercase 'A' as the starting point:

result.append(chr(ord('A') + remainder - 10))

3. Building the Result in Wrong Order

When converting to a different base, digits are extracted from least significant to most significant. Forgetting to reverse the result leads to backwards numbers.

Problem Code:

def convert_to_base(number: int, base: int) -> str:
    result = []
    while number > 0:
        # ... append digits to result
        number //= base
    return ''.join(result)  # Wrong: not reversed!

Solution: Remember to reverse the result before joining:

return ''.join(result[::-1])

4. Off-by-One Error in Letter Mapping

A subtle but critical error occurs when mapping numbers to letters. The mapping should be: 10→'A', 11→'B', ..., 35→'Z'.

Problem Code:

# Wrong: off-by-one error
if remainder >= 10:
    result.append(chr(ord('A') + remainder - 9))  # Should be -10, not -9

Solution: Use the correct offset of -10:

if remainder > 9:
    result.append(chr(ord('A') + remainder - 10))

5. Integer Overflow Concerns (Language-Specific)

While Python handles arbitrary precision integers automatically, in other languages like C++ or Java, calculating for large values of n could cause integer overflow.

Solution for Other Languages:

  • Use appropriate data types (long long in C++, BigInteger in Java)
  • Add input validation if needed
  • Consider the maximum value of n based on problem constraints

6. Incorrect Base Validation

Not validating that the base is within the supported range (2-36) could lead to incorrect results or runtime errors.

Solution: Add base validation:

def convert_to_base(number: int, base: int) -> str:
    if base < 2 or base > 36:
        raise ValueError(f"Base must be between 2 and 36, got {base}")
    # ... rest of the function
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

What are the two properties the problem needs to have for dynamic programming to be applicable? (Select 2)


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More