leetcode/solution/1900-1999/1922.Count Good Numbers/README.md

4.7 KiB
Raw Permalink Blame History

comments difficulty edit_url rating source tags
true 中等 https://github.com/doocs/leetcode/edit/main/solution/1900-1999/1922.Count%20Good%20Numbers/README.md 1674 第 248 场周赛 Q3
递归
数学

1922. 统计好数字的数目

English Version

题目描述

我们称一个数字字符串是 好数字 当它满足(下标从 0 开始)偶数 下标处的数字为 偶数 且 奇数 下标处的数字为 质数 (235 或 7)。

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

给你一个整数 n ,请你返回长度为 n 且为好数字的数字字符串 总数 。由于答案可能会很大,请你将它对 109 + 7 取余后返回 。

一个 数字字符串 是每一位都由 0 到 9 组成的字符串,且可能包含前导 0 。

 

示例 1

输入:n = 1
输出:5
解释:长度为 1 的好数字包括 "0""2""4""6""8" 。

示例 2

输入:n = 4
输出:400

示例 3

输入:n = 50
输出:564908303

 

提示:

  • 1 <= n <= 1015

解法

方法一:快速幂

长度为 n 的好数字,偶数下标一共有 \lceil \frac{n}{2} \rceil = \lfloor \frac{n + 1}{2} \rfloor 位,偶数下标可以填入 5 种数字(0, 2, 4, 6, 8);奇数下标一共有 \lfloor \frac{n}{2} \rfloor 位,奇数下标可以填入 4 种数字(2, 3, 5, 7)。因此长度为 n 的好数字的个数为:


ans = 5^{\lceil \frac{n}{2} \rceil} \times 4^{\lfloor \frac{n}{2} \rfloor}

我们可以使用快速幂来计算 5^{\lceil \frac{n}{2} \rceil}4^{\lfloor \frac{n}{2} \rfloor},时间复杂度为 O(\log n),空间复杂度为 O(1)

Python3

class Solution:
    def countGoodNumbers(self, n: int) -> int:
        mod = 10**9 + 7
        return pow(5, (n + 1) >> 1, mod) * pow(4, n >> 1, mod) % mod

Java

class Solution {
    private final int mod = (int) 1e9 + 7;

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

    private long qpow(long x, long n) {
        long res = 1;
        while (n != 0) {
            if ((n & 1) == 1) {
                res = res * x % mod;
            }
            x = x * x % mod;
            n >>= 1;
        }
        return res;
    }
}

C++

class Solution {
public:
    int countGoodNumbers(long long n) {
        const int mod = 1e9 + 7;
        auto qpow = [](long long x, long long n) -> long long {
            long long res = 1;
            while (n) {
                if ((n & 1) == 1) {
                    res = res * x % mod;
                }
                x = x * x % mod;
                n >>= 1;
            }
            return res;
        };
        return qpow(5, (n + 1) >> 1) * qpow(4, n >> 1) % mod;
    }
};

Go

const mod int64 = 1e9 + 7

func countGoodNumbers(n int64) int {
	return int(myPow(5, (n+1)>>1) * myPow(4, n>>1) % mod)
}

func myPow(x, n int64) int64 {
	var res int64 = 1
	for n != 0 {
		if (n & 1) == 1 {
			res = res * x % mod
		}
		x = x * x % mod
		n >>= 1
	}
	return res
}

TypeScript

function countGoodNumbers(n: number): number {
    const mod = 1000000007n;
    const qpow = (x: bigint, n: bigint): bigint => {
        let res = 1n;
        while (n > 0n) {
            if (n & 1n) {
                res = (res * x) % mod;
            }
            x = (x * x) % mod;
            n >>= 1n;
        }
        return res;
    };
    const a = qpow(5n, BigInt(n + 1) / 2n);
    const b = qpow(4n, BigInt(n) / 2n);
    return Number((a * b) % mod);
}