算法初探LeetCode-统计好数字的数目

165 阅读2分钟

LeetCode1922-统计好数字的数目

我们称一个数字字符串是 好数字 当它满足(下标从 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<=10151 <= n <= 10^{15}

思路分析

由题目可知,n代表数字字符串的位数,偶数位有5个数(0, 2, 4, 6, 8)可选,奇数位有4个(2, 3, 5, 7)可选

利用快速幂算法,一个数 & 1 的结果就是取二进制的最末位,判断最末位为0还是1,>>运算为去掉二进制数的最后一位,即右移一位。快速幂是对指数进行的,还需要用底数进行运算,每次乘法都要取模,防止变量溢出。

查看规律不难发现每增加一个数,增长的倍数有规律
即偶数变成奇数res4,而奇数变成偶数则是5,快速幂的原理很简单,就是让乘数翻倍。

算法代码

long mod = (int) 1e9 + 7;

public int countGoodNumbers(long n) {
    return (int)(pow(5, (n + 1) / 2) * pow(4, n / 2) % mod);
}

public long pow(int x, long n) {
    if (n == 0) return 1;
    if (n == 1) return x;
    if (n % 2 == 1) {
        return (x * pow(x, n - 1)) % mod;
    }
    long half = pow(x, n / 2);
    return half * half % mod;
}

结果详情

Snipaste_2023-05-07_23-41-44.png

算法复杂度

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!