1056. Confusing Number 🔒
Problem Description
A confusing number is a number that becomes a different number when rotated 180 degrees, with all digits remaining valid after rotation.
When we rotate individual digits by 180 degrees:
0
stays0
1
stays1
6
becomes9
8
stays8
9
becomes6
2
,3
,4
,5
, and7
become invalid (cannot be rotated)
The rotation process works by rotating each digit individually and reading the result from right to left. For example, if we have 69
:
- The
6
rotates to9
- The
9
rotates to6
- Reading from right to left gives us
96
Since 96 ≠ 69
, this is a confusing number.
Important notes:
- If any digit in the number cannot be rotated (like
2
,3
,4
,5
, or7
), the entire number is not a confusing number - Leading zeros after rotation are ignored (e.g.,
8000
rotated becomes0008
, which is just8
) - A confusing number must be different from the original number after rotation
Given an integer n
, determine if it's a confusing number by returning true
if it is, or false
otherwise.
The solution uses a mapping array d
where:
- Valid rotations are stored at their index positions (
d[0]=0
,d[1]=1
,d[6]=9
,d[8]=8
,d[9]=6
) - Invalid digits are marked with
-1
The algorithm extracts each digit from right to left, checks if it's rotatable, builds the rotated number, and finally compares it with the original.
Intuition
To determine if a number is confusing, we need to simulate the rotation process and check two conditions: all digits must be rotatable, and the final result must differ from the original.
The key insight is that we can process the number digit by digit from right to left, simultaneously building the rotated number from left to right. This naturally handles the rotation's "flip" effect where the rightmost digit becomes the leftmost after rotation.
Consider how rotation works visually: when you rotate 69
by 180 degrees, the 6
(on the left) becomes 9
and moves to the right position, while the 9
(on the right) becomes 6
and moves to the left position. This is equivalent to:
- Taking each digit from right to left
- Rotating it individually
- Appending it to build a new number from left to right
We can use a lookup table to make rotation efficient. Since we only have 10 possible digits (0-9), we can pre-define what each digit becomes after rotation:
- Rotatable digits:
0→0
,1→1
,6→9
,8→8
,9→6
- Non-rotatable digits:
2
,3
,4
,5
,7
→ invalid (we can mark these as-1
)
The algorithm naturally emerges:
- Extract the last digit using
divmod(n, 10)
- Check if it's rotatable using our lookup table
- If not rotatable, immediately return
false
- If rotatable, append its rotated value to build our result
- Continue until all digits are processed
- Compare the rotated number with the original
This approach elegantly handles leading zeros since we build the number mathematically (y = y * 10 + d[v]
), which automatically ignores leading zeros.
Learn more about Math patterns.
Solution Approach
The implementation uses a digit-by-digit extraction and reconstruction approach with a lookup table for efficient rotation mapping.
Data Structure:
- Lookup array
d = [0, 1, -1, -1, -1, -1, 9, -1, 8, 6]
where the index represents the original digit and the value represents its rotated form. Invalid rotations are marked as-1
.
Algorithm Steps:
-
Initialize variables:
x = n
: Copy of the original number for processingy = 0
: Will store the rotated numberd
: The rotation mapping array
-
Process each digit from right to left:
while x: x, v = divmod(x, 10)
divmod(x, 10)
gives us the quotient and remainderv
is the current rightmost digitx
becomes the remaining number after removing the rightmost digit
-
Check validity and rotate:
if d[v] < 0: return False
- If
d[v] < 0
, the digit cannot be rotated (it's one of 2, 3, 4, 5, 7) - Immediately return
False
as the number cannot be a confusing number
- If
-
Build the rotated number:
y = y * 10 + d[v]
- Multiply current
y
by 10 to shift digits left - Add the rotated digit
d[v]
to the rightmost position - This builds the rotated number from left to right as we extract digits from right to left
- Multiply current
-
Final comparison:
return y != n
- A confusing number must be different from the original after rotation
- Return
True
if they differ,False
if they're the same
Example walkthrough with n = 69
:
- First iteration:
x=69
,v=9
,d[9]=6
,y=0*10+6=6
,x=6
- Second iteration:
x=6
,v=6
,d[6]=9
,y=6*10+9=69
,x=0
- Loop ends, compare:
y=96 != n=69
, returnTrue
Example with invalid digit n = 25
:
- First iteration:
x=25
,v=5
,d[5]=-1 < 0
, returnFalse
immediately
This approach has O(log n)
time complexity (number of digits) and O(1)
space complexity.
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 n = 89
:
Step 1: Initialize
x = 89
(working copy)y = 0
(will build rotated number)d = [0, 1, -1, -1, -1, -1, 9, -1, 8, 6]
(rotation mapping)
Step 2: Extract rightmost digit (9)
x, v = divmod(89, 10)
→x = 8
,v = 9
- Check:
d[9] = 6
(valid, not -1) - Build rotated number:
y = 0 * 10 + 6 = 6
Step 3: Extract next digit (8)
x, v = divmod(8, 10)
→x = 0
,v = 8
- Check:
d[8] = 8
(valid, not -1) - Build rotated number:
y = 6 * 10 + 8 = 68
Step 4: No more digits
x = 0
, exit loop
Step 5: Compare results
- Original:
n = 89
- Rotated:
y = 68
- Since
68 ≠ 89
, returnTrue
Visual representation:
Original: 8 9 ↓ ↓ (rotate each digit) 8 6 ← ← (read right to left) Rotated: 6 8
The number 89 becomes 68 after rotation, making it a confusing number.
Solution Implementation
1class Solution:
2 def confusingNumber(self, n: int) -> bool:
3 """
4 Determines if a number is a confusing number.
5 A confusing number is a number that when rotated 180 degrees becomes a different number.
6
7 Args:
8 n: The input integer to check
9
10 Returns:
11 True if n is a confusing number, False otherwise
12 """
13 # Mapping of digits to their 180-degree rotated counterparts
14 # -1 means the digit cannot be rotated (like 2, 3, 4, 5, 7)
15 rotation_map = [0, 1, -1, -1, -1, -1, 9, -1, 8, 6]
16
17 # Keep original number for comparison
18 original_number = n
19
20 # Build the rotated number digit by digit
21 rotated_number = 0
22
23 # Process each digit from right to left
24 while original_number > 0:
25 # Extract the rightmost digit
26 original_number, current_digit = divmod(original_number, 10)
27
28 # Check if the digit can be rotated
29 rotated_digit = rotation_map[current_digit]
30 if rotated_digit < 0:
31 # This digit cannot be rotated, so not a valid confusing number
32 return False
33
34 # Build the rotated number (digits are added in reverse order)
35 rotated_number = rotated_number * 10 + rotated_digit
36
37 # A confusing number must be different after rotation
38 return rotated_number != n
39
1class Solution {
2 public boolean confusingNumber(int n) {
3 // Mapping array: index represents original digit, value represents rotated digit
4 // -1 means the digit cannot be rotated to form a valid digit
5 // 0->0, 1->1, 6->9, 8->8, 9->6
6 int[] rotationMap = new int[] {0, 1, -1, -1, -1, -1, 9, -1, 8, 6};
7
8 // Store original number and initialize rotated number
9 int originalNumber = n;
10 int rotatedNumber = 0;
11
12 // Process each digit from right to left
13 while (originalNumber > 0) {
14 // Extract the rightmost digit
15 int currentDigit = originalNumber % 10;
16
17 // Check if current digit can be rotated
18 if (rotationMap[currentDigit] < 0) {
19 // If digit cannot be rotated (2,3,4,5,7), number is not confusing
20 return false;
21 }
22
23 // Build the rotated number by appending the rotated digit
24 rotatedNumber = rotatedNumber * 10 + rotationMap[currentDigit];
25
26 // Remove the rightmost digit from original number
27 originalNumber /= 10;
28 }
29
30 // A confusing number is different from itself after rotation
31 return rotatedNumber != n;
32 }
33}
34
1class Solution {
2public:
3 bool confusingNumber(int n) {
4 // Mapping array: index represents original digit, value represents rotated digit
5 // -1 means the digit becomes invalid when rotated (2,3,4,5,7)
6 // 0->0, 1->1, 6->9, 8->8, 9->6
7 vector<int> rotationMap = {0, 1, -1, -1, -1, -1, 9, -1, 8, 6};
8
9 int originalNumber = n;
10 int rotatedNumber = 0;
11
12 // Process each digit from right to left
13 while (originalNumber > 0) {
14 // Extract the rightmost digit
15 int currentDigit = originalNumber % 10;
16
17 // Check if the digit is valid for rotation
18 if (rotationMap[currentDigit] < 0) {
19 return false; // Contains invalid digit (2,3,4,5,7)
20 }
21
22 // Build the rotated number by appending the rotated digit
23 rotatedNumber = rotatedNumber * 10 + rotationMap[currentDigit];
24
25 // Remove the processed digit
26 originalNumber /= 10;
27 }
28
29 // A confusing number is different from its rotated version
30 return rotatedNumber != n;
31 }
32};
33
1function confusingNumber(n: number): boolean {
2 // Mapping array: index represents original digit, value represents rotated digit
3 // -1 means the digit becomes invalid when rotated (2, 3, 4, 5, 7)
4 // 0->0, 1->1, 6->9, 8->8, 9->6
5 const rotationMap: number[] = [0, 1, -1, -1, -1, -1, 9, -1, 8, 6];
6
7 let originalNumber: number = n;
8 let rotatedNumber: number = 0;
9
10 // Process each digit from right to left
11 while (originalNumber > 0) {
12 // Extract the rightmost digit
13 const currentDigit: number = originalNumber % 10;
14
15 // Check if the digit is valid for rotation
16 if (rotationMap[currentDigit] < 0) {
17 // Contains invalid digit (2, 3, 4, 5, 7)
18 return false;
19 }
20
21 // Build the rotated number by appending the rotated digit
22 rotatedNumber = rotatedNumber * 10 + rotationMap[currentDigit];
23
24 // Remove the processed digit
25 originalNumber = Math.floor(originalNumber / 10);
26 }
27
28 // A confusing number is different from its rotated version
29 return rotatedNumber !== n;
30}
31
Time and Space Complexity
Time Complexity: O(log n)
The algorithm iterates through each digit of the number n
. Since a number n
has ⌊log₁₀(n)⌋ + 1
digits, the while loop executes O(log n)
times. In each iteration, we perform constant time operations:
divmod(x, 10)
:O(1)
- Array lookup
d[v]
:O(1)
- Multiplication and addition
y * 10 + d[v]
:O(1)
Therefore, the overall time complexity is O(log n)
.
Space Complexity: O(1)
The algorithm uses a fixed amount of extra space:
- Variable
x
to store a copy ofn
:O(1)
- Variable
y
to build the rotated number:O(1)
- Variable
v
to store the current digit:O(1)
- Array
d
with 10 elements (constant size):O(1)
The space usage doesn't grow with the input size, making the space complexity O(1)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Modifying the Original Number Variable
A critical mistake is using the original number variable n
for digit extraction, which destroys the original value needed for the final comparison.
Incorrect approach:
def confusingNumber(self, n: int) -> bool:
rotation_map = [0, 1, -1, -1, -1, -1, 9, -1, 8, 6]
rotated = 0
# ERROR: Modifying n directly loses the original value
while n > 0:
n, digit = divmod(n, 10) # n is being modified!
if rotation_map[digit] < 0:
return False
rotated = rotated * 10 + rotation_map[digit]
return rotated != n # This will always compare with 0!
Solution: Create a copy of n
for processing:
original_number = n # Keep n intact
while original_number > 0:
original_number, digit = divmod(original_number, 10)
# ... rest of the logic
return rotated != n # Now n still has the original value
2. Incorrect Rotation Building Order
Another common mistake is building the rotated number in the wrong order, either by prepending digits instead of appending or by not understanding the rotation reversal.
Incorrect approach:
# Wrong: Trying to prepend digits (this doesn't work as intended) rotated = d[v] * (10 ** digit_position) + rotated
Correct approach: The digits should be added from left to right as we extract from right to left:
rotated = rotated * 10 + rotation_map[digit]
3. Forgetting to Handle Single Valid Digits
Numbers like 0
, 1
, and 8
rotate to themselves. Beginners might incorrectly assume these should return True
because they're "valid for rotation."
Key insight: A confusing number must be different after rotation. So:
8
→8
: Not confusing (returnsFalse
)6
→9
: Confusing (returnsTrue
)88
→88
: Not confusing (returnsFalse
)68
→89
: Confusing (returnsTrue
)
4. Index Out of Bounds for Large Digits
If the rotation map array has exactly 10 elements but you don't validate the digit range, you could get an index error.
Prevention: While digits from divmod
are guaranteed to be 0-9, if you're getting digits differently, always validate:
if current_digit < 0 or current_digit > 9: return False
5. Not Handling Zero Correctly
The number 0
is a special case that rotates to itself (0
→ 0
), so it should return False
. Make sure your logic handles this correctly and doesn't have any division by zero or infinite loop issues.
Which data structure is used to implement priority queue?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
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
Want a Structured Path to Master System Design Too? Don’t Miss This!