leetcode 1088
问题 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.(Note that the rotated number can be greater than the original number.)
Given a positive integer N
, return the number of confusing numbers between 1
and N
inclusive.
Example 1:
1 2 3 4 5 6 7 8 9 10 Input: 20 Output: 6 Explanation: The confusing numbers are [6,9,10,16,18,19]. 6 converts to 9. 9 converts to 6. 10 converts to 01 which is just 1. 16 converts to 91. 18 converts to 81. 19 converts to 61.
Example 2:
1 2 3 4 Input: 100 Output: 19 Explanation: The confusing numbers are [6,9,10,16,18,19,60,61,66,68,80,81,86,89,90,91,98,99,100].
Note:
1 <= N <= 10^9
分析 思路1: 由 0, 1, 6, 8, 9 进行排列组合出所有有可能是 Confusing Number 的数组,然后再判断其是否是 Confusing Number。
思路2: 由 0, 1, 6, 8, 9 进行排列组合出的所有小于等于N组合数中,不是 Confusing Number 就是Strobogrammatic Number,且 Strobogrammatic Number 的数量要远小于 Confusing Number的数量。因此,可以使用总数量减去 Strobogrammatic Number 的数量来得到 Confusing Number 的数量。
代码1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Solution {public : int a[5 ] = {0 , 1 , 6 , 8 , 9 }; int b[10 ] = {0 , 1 , -2 , -3 , -4 , -5 , 9 , -7 , 8 , 6 }; bool isConfusingNumber (long long X) { long long rx = 0 ; long long x = X; while (X > 0 ) { rx = rx*10 + b[X%10 ]; X/=10 ; } return rx==x? false : true ; } int confusingNumberII (int N) { queue <long long > q; int ans = 0 ; if (N < 6 ) return 1 ; if (N < 9 ) return 2 ; for (int i = 1 ; i < 5 ; ++i) { q.push(a[i]); } bool enough = false ; while (q.size() != 0 ) { long long x = q.front(); q.pop(); if (isConfusingNumber(x)) ans++; if (enough == false ) { for (int i = 0 ; i < 5 ; ++i) { long long y = x*10 + a[i]; if (y <= N) q.push(y); else enough = true ; } } } return ans; } };
代码2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : int a[5 ] = {0 , 1 , 6 , 8 , 9 }; int b[10 ] = {0 , 1 , -2 , -3 , -4 , -5 , 9 , -7 , 8 , 6 }; bool isConfusingNumber (long long X) { long long rx = 0 ; long long x = X; while (X > 0 ) { rx = rx*10 + b[X%10 ]; X/=10 ; } return rx==x? false : true ; } int confusingNumberII (int N) { int ans = 0 ; for (int i = 1 ; i < 5 ; ++i) { dfs(a[i], N, ans); } return ans; } void dfs (long long num, int N, int &ans) { if (num > N) return ; if (isConfusingNumber(num)) ans++; for (int i = 0 ; i < 5 ; ++i) { dfs(num*10 + a[i], N, ans); } } };
代码3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 class Solution {public : vector <vector <char >> pairs = {{'0' ,'0' }, {'1' ,'1' }, {'6' ,'9' }, {'8' ,'8' }, {'9' ,'6' }}; int a[10 ] = {0 , 1 , -1 , -1 , -1 , -1 , 9 , -1 , 8 , 6 }; int confusingNumberII (int N) { int ans = 0 ; string n = to_string(N); ans = getTotalNumber(n); for (int len = 1 ; len <= n.size(); ++len) { string s (len, '0' ) ; ans -= dfs(n, s, 0 , len-1 ); } return ans; } int dfs (const string &n, string s, int l, int r) { int ret = 0 ; if (l > r) { if (s.size() == n.size() && s > n) return 0 ; else return 1 ; } else { for (vector <char > &p: pairs) { s[l] = p[0 ]; s[r] = p[1 ]; if (s.size() != 1 && s[0 ] == '0' ) continue ; if (l==r && p[0 ]!=p[1 ]) continue ; ret += dfs(n, s, l+1 , r-1 ); } } return ret; } int getTotalNumber (string n) { int ret = 0 ; if (n.size() == 1 ) { ret = count(n[0 ]+1 ); } else { ret = count(n[0 ])*pow (5 , n.size()-1 ); if (a[n[0 ]-'0' ] >= 0 ) ret += getTotalNumber(n.substr(1 )); } return ret; } int count (char c) { int ret = 0 ; for (vector <char > &p: pairs) { if (c > p[0 ]) ret++; } return ret; } };