LeetCode 1056: Confusing Number (Rotate-and-Compare)
LeetCode 1056MathSimulationToday we solve LeetCode 1056 - Confusing Number.
Source: https://leetcode.com/problems/confusing-number/
English
Problem Summary
A number is confusing if after rotating each digit by 180 degrees, we get a valid but different number. Valid mappings are: 0→0, 1→1, 6→9, 8→8, 9→6.
Key Insight
Build the rotated number from right to left: take the last digit, map it, and append it to a new number. If any digit is invalid (2,3,4,5,7), return false immediately. Finally compare with the original number.
Algorithm
- Keep a rotation map for valid digits.
- Iterate through digits of n from least significant to most significant.
- If a digit is not in the map, return false.
- Build rotated = rotated * 10 + map[d].
- Return rotated != n.
Complexity Analysis
Let k be number of digits.
Time: O(k).
Space: O(1).
Common Pitfalls
- Forgetting that invalid digits must fail immediately.
- Rotating left-to-right and accidentally reversing order incorrectly.
- Treating unchanged numbers like 11 or 69? no as confusing without checking difference properly.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public boolean confusingNumber(int n) {
int original = n;
int rotated = 0;
while (n > 0) {
int d = n % 10;
if (d == 2 || d == 3 || d == 4 || d == 5 || d == 7) {
return false;
}
if (d == 6) d = 9;
else if (d == 9) d = 6;
rotated = rotated * 10 + d;
n /= 10;
}
return rotated != original;
}
}func confusingNumber(n int) bool {
original := n
rotated := 0
for n > 0 {
d := n % 10
if d == 2 || d == 3 || d == 4 || d == 5 || d == 7 {
return false
}
if d == 6 {
d = 9
} else if d == 9 {
d = 6
}
rotated = rotated*10 + d
n /= 10
}
return rotated != original
}class Solution {
public:
bool confusingNumber(int n) {
int original = n;
long long rotated = 0;
while (n > 0) {
int d = n % 10;
if (d == 2 || d == 3 || d == 4 || d == 5 || d == 7) {
return false;
}
if (d == 6) d = 9;
else if (d == 9) d = 6;
rotated = rotated * 10 + d;
n /= 10;
}
return rotated != original;
}
};class Solution:
def confusingNumber(self, n: int) -> bool:
original = n
rotated = 0
while n > 0:
d = n % 10
if d in (2, 3, 4, 5, 7):
return False
if d == 6:
d = 9
elif d == 9:
d = 6
rotated = rotated * 10 + d
n //= 10
return rotated != original/**
* @param {number} n
* @return {boolean}
*/
var confusingNumber = function(n) {
const original = n;
let rotated = 0;
while (n > 0) {
let d = n % 10;
if (d === 2 || d === 3 || d === 4 || d === 5 || d === 7) {
return false;
}
if (d === 6) d = 9;
else if (d === 9) d = 6;
rotated = rotated * 10 + d;
n = Math.floor(n / 10);
}
return rotated !== original;
};中文
题目概述
如果一个数字每一位旋转 180 度后,仍然是合法数字且与原数字不同,则称为 confusing number。合法映射是:0→0, 1→1, 6→9, 8→8, 9→6。
核心思路
从低位到高位处理原数,每次取出末位并做旋转映射,然后追加到新数字末尾。若出现非法数字(2/3/4/5/7)直接返回 false。最后比较旋转结果是否与原数不同。
算法步骤
- 准备有效旋转映射。
- 循环取 n 的末位数字。
- 若该位非法,直接返回 false。
- 按映射构造 rotated = rotated * 10 + mappedDigit。
- 最终返回 rotated != original。
复杂度分析
设数字位数为 k。
时间复杂度:O(k)。
空间复杂度:O(1)。
常见陷阱
- 忘记对非法数字直接判失败。
- 构造旋转数时位序处理错误。
- 没有比较是否“与原数不同”,把 11、88 误判为 confusing。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public boolean confusingNumber(int n) {
int original = n;
int rotated = 0;
while (n > 0) {
int d = n % 10;
if (d == 2 || d == 3 || d == 4 || d == 5 || d == 7) {
return false;
}
if (d == 6) d = 9;
else if (d == 9) d = 6;
rotated = rotated * 10 + d;
n /= 10;
}
return rotated != original;
}
}func confusingNumber(n int) bool {
original := n
rotated := 0
for n > 0 {
d := n % 10
if d == 2 || d == 3 || d == 4 || d == 5 || d == 7 {
return false
}
if d == 6 {
d = 9
} else if d == 9 {
d = 6
}
rotated = rotated*10 + d
n /= 10
}
return rotated != original
}class Solution {
public:
bool confusingNumber(int n) {
int original = n;
long long rotated = 0;
while (n > 0) {
int d = n % 10;
if (d == 2 || d == 3 || d == 4 || d == 5 || d == 7) {
return false;
}
if (d == 6) d = 9;
else if (d == 9) d = 6;
rotated = rotated * 10 + d;
n /= 10;
}
return rotated != original;
}
};class Solution:
def confusingNumber(self, n: int) -> bool:
original = n
rotated = 0
while n > 0:
d = n % 10
if d in (2, 3, 4, 5, 7):
return False
if d == 6:
d = 9
elif d == 9:
d = 6
rotated = rotated * 10 + d
n //= 10
return rotated != original/**
* @param {number} n
* @return {boolean}
*/
var confusingNumber = function(n) {
const original = n;
let rotated = 0;
while (n > 0) {
let d = n % 10;
if (d === 2 || d === 3 || d === 4 || d === 5 || d === 7) {
return false;
}
if (d === 6) d = 9;
else if (d === 9) d = 6;
rotated = rotated * 10 + d;
n = Math.floor(n / 10);
}
return rotated !== original;
};
Comments