Prerequisites
Before attempting this problem, you should be comfortable with:
- Hash Maps / Dictionaries - Used to map digits to their rotated counterparts for O(1) lookup
- String Manipulation - Converting integers to strings and reversing strings
- Modular Arithmetic - Extracting digits using modulo and integer division operations
1. Invert and Reverse
Intuition
A confusing number looks different when rotated 180 degrees. Only digits 0, 1, 6, 8, and 9 remain valid after rotation (6 becomes 9 and vice versa). We invert each digit, reverse the result, and check if it differs from the original.
Algorithm
- Create a mapping of valid digits to their rotated counterparts:
0->0,1->1,6->9,8->8,9->6. - Iterate through each digit of
nas a string. - If any digit is not in the map (
2,3,4,5,7), returnfalseimmediately. - Build the rotated number by appending the inverted digit for each character.
- Reverse the rotated number and compare it to the original. If different, return
true.
class Solution:
def confusingNumber(self, n: int) -> bool:
# Use 'invertMap' to invert each valid digit.
invert_map = {"0":"0", "1":"1", "8":"8", "6":"9", "9":"6"}
rotated_number = []
# Iterate over each digit of 'n'.
for ch in str(n):
if ch not in invert_map:
return False
# Append the inverted digit of 'ch' to the end of 'rotated_number'.
rotated_number.append(invert_map[ch])
rotated_number = "".join(rotated_number)
# Check if the reversed 'rotated_number' equals 'n'.
return int(rotated_number[::-1]) != nTime & Space Complexity
- Time complexity:
- Space complexity: extra space used
Where is the maximum number of digits can have ().
2. Use the remainder
Intuition
Instead of converting to a string, we can extract digits using modular arithmetic. Processing digits from right to left while building the rotated number from left to right naturally produces the reversed rotated version.
Algorithm
- Create a mapping of valid digits (
0,1,6,8,9) to their rotated values. - Make a copy of
nand initialize the rotated number to0. - Extract digits using modulo
10. If a digit is invalid, returnfalse. - Build the rotated number by multiplying by
10and adding the inverted digit. - Divide the copy by
10to move to the next digit. After processing all digits, compare the rotated number to the original.
class Solution:
def confusingNumber(self, n: int) -> bool:
# Use 'invert_map' to invert each valid digit. Since we don't want to modify
# 'n', we create a copy of it as 'nCopy'.
invert_map = {0:0, 1:1, 8:8, 6:9, 9:6}
invert_number = 0
n_copy = n
# Get every digit of 'n_copy' by taking the remainder of it to 10.
while n_copy:
res = n_copy % 10
if res not in invert_map:
return False
# Append the inverted digit of 'res' to the end of 'rotated_number'.
invert_number = invert_number * 10 + invert_map[res]
n_copy //= 10
# Check if 'rotated_number' equals 'n'.
return invert_number != nTime & Space Complexity
- Time complexity:
- Space complexity: extra space used
Where is the maximum number of digits can have.
Common Pitfalls
Confusing "Different" with "Invalid"
A confusing number must be valid (all digits can be rotated) AND look different after rotation. Returning true for invalid digits like 2, 3, 4, 5, 7 instead of returning false is incorrect.
# Wrong: treats invalid digits as confusing
if ch not in invert_map:
return True # Should be False
# Correct
if ch not in invert_map:
return FalseForgetting to Reverse After Inversion
Rotating 180 degrees means both inverting each digit AND reversing their order. Only inverting without reversing (or vice versa) gives the wrong result. For example, 69 inverts to 96 but must then reverse to 69, so 69 is NOT confusing.