【LetMeFly】1922.统计好数字的数目:乘法原理+快速幂
力扣题目链接:https://leetcode.cn/problems/count-good-numbers/
我们称一个数字字符串是 好数字 当它满足(下标从 0 开始)偶数 下标处的数字为 偶数 且 奇数 下标处的数字为 质数 (2
,3
,5
或 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
解题方法:乘法原理+快速幂
每个偶数下标有5种选择,每个奇数下标有4种选择,每个元素之间的选择互补干扰冲突。
由于共有 a = ⌊ n + 1 2 ⌋ a=\lfloor\frac{n+1}{2}\rfloor a=⌊2n+1⌋个偶数位和 b = ⌊ n 2 ⌋ b=\lfloor\frac{n}{2}\rfloor b=⌊2n⌋个奇数位,所以一共有 5 a 4 b 5^a4^b 5a4b种答案。
如何快速计算 m n m^n mn?使用快速幂可在 log n \log n logn的时间复杂度内求出。
快速幂原理方法请见:这里。
- 时间复杂度 O ( log n ) O(\log n) O(logn)
- 空间复杂度 O ( 1 ) O(1) O(1)
AC代码
C++
/*
* @Author: LetMeFly
* @Date: 2025-04-13 17:00:20
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-04-13 17:06:07
* @Description: AC,100.00%,51.97%
*/
typedef long long ll;
const ll MOD = 1e9 + 7;
class Solution {
private:
ll pow(ll a, ll b) {
ll ans = 1;
while (b) {
if (b & 1) {
ans = ans * a % MOD;
}
a = a * a % MOD;
b >>= 1;
}
return ans;
}
public:
int countGoodNumbers(long long n) {
return pow(5, (n + 1) / 2) * pow(4, n / 2) % MOD;
}
};
Python
Python用户可以无视手动实现快速幂。
'''
Author: LetMeFly
Date: 2025-04-13 17:06:16
LastEditors: LetMeFly.xyz
LastEditTime: 2025-04-13 17:06:17
'''
MOD = 1000000007
class Solution:
def countGoodNumbers(self, n: int) -> int:
return pow(5, (n + 1) // 2, MOD) * pow(4, n // 2, MOD) % MOD
Java
/*
* @Author: LetMeFly
* @Date: 2025-04-13 17:07:43
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-04-14 00:07:21
* @Description: AC,100.00%,87.23%
*/
class Solution {
private final long mod = 1000000007;
private long pow(long a, long b) {
long ans = 1;
while (b > 0) {
if ((b & 1) == 1) {
ans = ans * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return ans;
}
public int countGoodNumbers(long n) {
return (int)(pow(5, (n + 1) / 2) * pow(4, n / 2) % mod);
}
}
Golang
/*
* @Author: LetMeFly
* @Date: 2025-04-13 17:54:42
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-04-14 00:05:17
* @Description: continue on subway,太晃了还是先算了
* @Description: AC,100.00%,63.16%
*/
package main
var MOD1922 = int64(1000000007)
func pow1922(a int64, b int64) int64 {
ans := int64(1)
for ; b > 0; b >>= 1 {
if b & 1 == 1 {
ans = ans * a % MOD1922
}
a = a * a % MOD1922
}
return ans
}
func countGoodNumbers(n int64) int {
return int(pow1922(5, (n + 1) / 2) * pow1922(4, n / 2) % MOD1922)
}
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源