X is a good number if after rotating each digit individually by 180 degrees, we get a valid number that is different from X. A number is valid if each digit remains a digit after rotation. 0, 1, and 8 rotate to themselves; 2 and 5 rotate to each other; 6 and 9 rotate to each other, and the rest of the numbers do not rotate to any other number.
Now given a positive number N
, how many numbers X from 1
to N
are good?
Example: Input: 10 Output: 4 Explanation: There are four good numbers in the range [1, 10] : 2, 5, 6, 9. Note that 1 and 10 are not good numbers, since they remain unchanged after rotating.
Note:
- N will be in range
[1, 10000]
.
我原本打算用排列组合判断N中有多少个能满足条件的数,但是发现用排列组合思路太复杂了,把自己绕进去了,在这种 contest 中还是用比较容易又不会 time out 的 O(n) 解法比较保险。
不如直接从1遍历到N,判断每一个数是否满足 valid 的条件。毕竟这是一道 easy 题啊。
public class Rotated_Digits_788 {
//018
//至少一个2569
//不能有347
public int rotatedDigits(int N) {
int count=0;
for(int i=1;i<=N;i++){
if(isValid(i)){
count++;
}
}
return count;
}
public boolean isValid(int n){
boolean find2569=false;
while(n>0){
int digit=n%10;
if(digit==2||digit==5||digit==6||digit==9){
find2569=true;
}
if(digit==3||digit==4||digit==7){
return false;
}
n=n/10;
}
return find2569;
}
public static void main(String[] args) {
Rotated_Digits_788 r=new Rotated_Digits_788();
System.out.println(r.rotatedDigits(857));
}
}
看了看discuss,有大神用正则做。正则确实比较清晰明了,不过就是性能有点差。
public int rotatedDigits(int N) {
int count = 0;
for(int i = 1; i <= N; i++) {
if (Integer.toString(i).matches("^([018]*[2569]+[018]*)+$"))
count++;
}
return count;
}
//One line in java 8:
public int rotatedDigits(int N) { return IntStream.range(1, N+1).map(i -> Integer.toString(i).matches("^([018]*[2569]+[018]*)+$") ? 1 : 0).sum();}
不过应该有log(n)的解法(用排列组合写的话),放个链接之后学习:https://leetcode.com/problems/rotated-digits/discuss/