[LeetCode] 1056. Confusing Number 混淆的數字



Given a number N, return true if and only if it is a confusing number, which satisfies the following condition:

We can rotate digits by 180 degrees to form new digits. When 0, 1, 6, 8, 9 are rotated 180 degrees, they become 0, 1, 9, 8, 6 respectively. When 2, 3, 4, 5 and 7 are rotated 180 degrees, they become invalid. A confusing number is a number that when rotated 180 degrees becomes a different number with each digit valid.

Example 1:

Input: 6
Output: true
Explanation:
We get `9` after rotating `6`, `9` is a valid number and `9!=6`.

Example 2:

Input: 89
Output: true
Explanation:
We get `68` after rotating `89`, `86` is a valid number and `86!=89`.

Example 3:

Input: 11
Output: false
Explanation:
We get `11` after rotating `11`, `11` is a valid number but the value remains the same, thus `11` is not a confusing number.

Example 4:

Input: 25
Output: false
Explanation:
We get an invalid number after rotating `25`.

Note:

  1. 0 <= N <= 10^9
  2. After the rotation we can ignore leading zeros, for example if after rotation we have 0008 then this number is considered as just 8.

這道題定義了一種迷惑數,將數字翻轉 180 度,其中 0, 1, 8 旋轉后保持不變,6變成9,9變成6,數字 2, 3, 4, 5, 和 7 旋轉后變為非法數字。若能將某個數翻轉后成為一個合法的新的數,就說這個數是迷惑數。這道題的難度並不大,就是考察的是遍歷整數各個位上的數字,使用一個 while 循環,然后用 mod10 取出當前最低位上的數字,將不合法的數字放入一個 HashSet 中,這樣直接在 HashSet 中查找一下當前數字是否存在,存在直接返回 false。不存在的話,則要進行翻轉,因為只有6和9兩個數字翻轉后會得到不同的數字,所以單獨判斷一下,然后將當前數字拼到 num 的最低位即可,最終拼成的 num 就是原數字 N 的翻轉,最后別忘了比較一下是否相同,參見代碼如下:


解法一:

class Solution {
public:
    bool confusingNumber(int N) {
        int num = 0, oldN = N;
        unordered_set<int> invalid{{2, 3, 4, 5, 7}};
        while (N > 0) {
            int digit = N % 10;
            if (invalid.count(digit)) return false;
            if (digit == 6) digit = 9;
            else if (digit == 9) digit = 6;
            num = num * 10 + digit;
            N /= 10;
        }
        return num != oldN;
    }
};

這也可以用一個 HashMap 來建立所有的數字映射,然后還是用一個變量 oldN 來記錄原來的數字,然后遍歷N上的每一位數字,若其不在 HashMap 中,說明有數字無法翻轉,直接返回 false,否則就把翻轉后的數字加入 res,最后只要看 res 和 oldN 是否相等即可,參見代碼如下:


解法二:

class Solution {
public:
    bool confusingNumber(int N) {
        unordered_map<int, int> m{{0, 0}, {1, 1}, {6, 9}, {8, 8}, {9, 6}};
        long oldN = N, res = 0;
        while (N > 0) {
            if (!m.count(N % 10)) return false;
            res = res * 10 + m[N % 10];
            N /= 10;
        }
        return res != oldN;
    }
};

下面來看一種雙指針的解法,這里先用一個數組 rotate 來按位記錄每個數字翻轉后得到的數字,用 -1 來表示非法情況,然后將數字 N 轉為字符串,用兩個指針 left 和 right 分別指向開頭和末尾。用 while 循環進行遍歷,假如此時 left 和 right 中有任何一個指向的數字翻轉后是非法,直接返回 false。然后看 left 指向的數字翻轉后跟 right 指向的數字是否相同,若不同,則將 res 標記為 true,然后移動 left 和 right 指針,最終返回 res 即可,參見代碼如下:


解法三:

class Solution {
public:
    bool confusingNumber(int N) {
        bool res = false;
        vector<int> rotate{0, 1, -1, -1, -1, -1, 9, -1, 8, 6};
        string str = to_string(N);
        int n = str.size(), left = 0, right = n - 1;
        while (left <= right) {
            if (rotate[str[left] - '0'] == -1 || rotate[str[right] - '0'] == -1) return false;
            if (rotate[str[left] - '0'] != (str[right] - '0')) res = true;
            ++left; --right;
        }
        return res;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1056


類似題目:

Strobogrammatic Number

Confusing Number II


參考資料:

https://leetcode.com/problems/confusing-number/

https://leetcode.com/problems/confusing-number/discuss/303832/Java-Solution-using-HashMap-Similar-to-246.-Strobogrammatic-Number

https://leetcode.com/problems/confusing-number/discuss/398574/Java-0ms-12-line-solution-with-two-pointers


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM