Weekly Contest 73 leetcode 788. Rotated Digits

257 篇文章 17 订阅

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].
这道题意思是,一个数 valid 的条件是这个数不包含 3, 4, 7 且包含至少一个 2, 5, 6, 9。

我原本打算用排列组合判断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/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值