题目
我们称一个数字字符串是“好数字”当它满足(下标从 0 开始)偶数下标处的数字为偶数且奇数下标处的数字为质数(2,3,5 或 7)。
比方说,“2582” 是好数字,因为偶数下标处的数字(2 和 8)是偶数且奇数下标处的数字(5 和 2)为质数。但 “3245” 不是好数字,因为 3 在偶数下标处但不是偶数。
给你一个整数 n ,请你返回长度为 n 且为好数字的数字字符串总数 。由于答案可能会很大,请你将它对 10^9 + 7取余后返回 。
一个数字字符串是每一位都由 0 到 9 组成的字符串,且可能包含前导 0 。
示例 1:
输入:n = 1
输出:5
解释:长度为 1 的好数字包括 "0","2","4","6","8" 。
示例 2:
输入:n = 4
输出:400
示例 3:
输入:n = 50
输出:564908303
提示:
1 <= n <= 10^15
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-good-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
由题目可轻松得出。当数字下标为奇数时,有2,3,5,7四种可能。当下标为偶数时,有0,2,4,6,8五种可能。且题目允许包含前导0。我们只需求出所有排列组合
一、暴力破解
class Solution {
public int countGoodNumbers(long n) {
long ans=1;
for (long i=0;i<n;i++){
if (i%2==0){
ans*=5;
}else {
ans*=4;
}
ans%=(1_000_000_000+7);
}
return (int)ans;
}
}
由于数字的位数为n,我们可以用一个for循环解决问题。但是,需要注意题目n的范围。毫无疑问,当n=10^15,肯定会超时。这时我们可以换一种算法,通过递归求出结果。
二、递归
class Solution {
public int countGoodNumbers(long n) {
//x为乘4个数,y为乘5个数
long x=n/2;
long y=n-x;
x = pow(4l, x);
y = pow(5l,y);
return (int) ((x * y) % (1_000_000_000 + 7));
}
long pow(long x,long n){
if(n==0)
return 1;
if(n==1)
return x;
long num=pow(x,n/2);
if (n%2==0){
return (num*num)% (1_000_000_000 + 7);
}else {
return (num*num*x)% (1_000_000_000 + 7);
}
}
}
由代码可以看出,递归的时间复杂度为O(log2(n))。除了上面这种写法外,我们也可以使用栈来实现递归
三、栈实现快速幂
class Solution {
public int countGoodNumbers(long n) {
//x为乘4个数,y为乘5个数
long x=n/2;
long y=n-x;
x = pow(4l, x);
y = pow(5l,y);
return (int) ((x * y) % (1_000_000_000 + 7));
}
long pow(long x,long n){
LinkedList<Long> stack=new LinkedList<>();
while (n!=0){
stack.push(n % 2 == 0?1l:x);
n/=2;
}
long ans=1l;
while (!stack.isEmpty()){
ans*=ans*stack.pop();
ans%=(1_000_000_000+7);
}
return ans;
}
}
四、位运算实现快速幂
class Solution {
public int countGoodNumbers(long n) {
//x为乘4个数,y为乘5个数
long x=n/2;
long y=n-x;
x = pow(4l, x);
y = pow(5l,y);
return (int) ((x * y) % (1_000_000_000 + 7));
}
long pow(long x,long n){
long ans=1;
while (n!=0){
if ((n&1)==1){
ans=ans*x;
}
x*=x;
x%=1_000_000_000+7;
ans%=1_000_000_000+7;
n>>=1;
}
return ans;
}
}
此方法为快速幂实现模板,通过位移实现对x求幂。
总结
以上就是常用的几种快速幂算法,若上诉有错误或者能够改进的地方,欢迎大家指出纠正。