【Leetcode 每日一题】1922. 统计好数字的数目

问题背景

我们称一个数字字符串是 好数字 当它满足(下标从 0 0 0 开始)偶数 下标处的数字为 偶数奇数 下标处的数字为 质数 ( 2 ,   3 ,   5 (2, \ 3, \ 5 (2, 3, 5 7 ) 7) 7)

  • 比方说,“2582” 是好数字,因为偶数下标处的数字 ( 2 (2 (2 8 ) 8) 8) 是偶数且奇数下标处的数字 ( 5 (5 (5 2 ) 2) 2) 为质数。但 “3245” 不是好数字,因为 3 3 3 在偶数下标处但不是偶数。

给你一个整数 n n n,请你返回长度为 n n n 且为好数字的数字字符串 总数 。由于答案可能会很大,请你将它对 ( 1 0 9 + 7 ) (10 ^ 9 + 7) (109+7) 取余后返回
一个 数字字符串 是每一位都由 0 0 0 9 9 9 组成的字符串,且可能包含前导 0 0 0

数据约束

  • 1 ≤ n ≤ 1 0 15 1 \le n \le 10 ^ {15} 1n1015

解题过程

注意题目中的 n n n 表示数据的长度而不是范围,对长度可能达到 1 0 15 10 ^ {15} 1015 量级的数字,用暴力解是一定会超时的。
给定的数字中允许包含前导 0 0 0,实际上意味着每个整数奇数位上的数字和偶数位上的数字可能性是确定的,这是一个纯粹的排列组合问题。
考虑到数据范围特别大,结果需要用 快速幂 来计算。

具体实现

class Solution {
    private static final int MOD = 1000000007;

    public int countGoodNumbers(long n) {
        return (int) (pow(5, (n + 1) >> 1) * pow(4, n >> 1) % MOD);
    }

    private long pow (long x, long n) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) > 0) {
                res = res * x % MOD;
            }
            x = x * x % MOD;
            n >>= 1;
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值