1920. 基于排列构建数组
思路分析
同样是模拟,放到第一题的问题就会简单的离谱,所有的规则都在谜面上,ans[i] = nums[nums[i]]
没必要继续分析和贴代码了。
1922. 统计好数字的数目
思路分析
偶数和质数本身在解题过程中是完全没有意义的,我们可以看到其实只是偶数下标处有5种可能,奇数下标处有4种可能。
那么我们可以写出一个简单的递归代码
class Solution {
public:
int flag = 1;
int x = 1000000007;
int countGoodNumbers(long long n) {
if (n == 1)return 4 + flag;
if (flag == 0){
flag = 1;
}else{
flag = 0;
}
int t = 5 - flag;
return countGoodNumbers(n - 1) * t % x;
}
};
这里通过flag控制每次是5次还是4次,不过我们会发现没有必要通过递归,由于下标从0开始,我们可以知道,当n等于偶数的时候,偶数下标和奇数下标都有n/2个。当n等于奇数的时候,偶数下标会比奇数下标多一个,奇数下标等于(n - 1)/2,偶数下标等于(n - 1)/ 2 + 1个,不过由于代码计算除法向下取整,所以奇数下标可以为n/2个,偶数下标也就是(n + 1)/2个或者n/2+1个。
所以有
if (n % 2 == 0){
return 5^(n/2)+4^(n/2);
}else{
return 5 ^(n/2 + 1) + 4^(n/2);
}
但是当n过大的时候,很容易时间过长。因此可以使用快速幂来计算:
while (y > 0) {
if (y % 2 == 1) {
ret = (long long)ret * mul % x;
}
mul = (long long)mul * mul % x;
y /= 2;
}
从代码中可以易见,这种计算方式会使mul指数级增长。 快速幂时间复杂度等于,同连乘相比更加快捷,同时还可以控制数据及时取模不会溢出。