LeetCode 1922.统计好数字的数目:乘法原理+快速幂

【LetMeFly】1922.统计好数字的数目:乘法原理+快速幂

力扣题目链接:https://leetcode.cn/problems/count-good-numbers/

我们称一个数字字符串是 好数字 当它满足(下标从 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

解题方法:乘法原理+快速幂

每个偶数下标有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和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tisfy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值