持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
前言
今天的题目为简单,题目虽然简单,但是还是需要一点关于数学排列组合的知识,知道的话就确实是一道简单题。
每日一题
今天的题目是 1175. 质数排列,难度为简单
-
请你帮忙给从 1 到 n 的数设计排列方案,使得所有的「质数」都应该被放在「质数索引」(索引从 1 开始)上;你需要返回可能的方案总数。
-
让我们一起来回顾一下「质数」:质数一定是大于 1 的,并且不能用两个小于它的正整数的乘积来表示。
-
由于答案可能会很大,所以请你返回答案 模 mod 10^9 + 7 之后的结果即可。
示例 1:
输入:n = 5
输出:12
解释:举个例子,[1,2,5,4,3] 是一个有效的排列,但 [5,2,3,4,1] 不是,因为在第二种情况里质数 5 被错误地放在索引为 1 的位置上。
示例 2:
输入:n = 100
输出:682289015
提示:
- 1 <= n <= 100
题解
模拟
题目的要求比较简单,就是纯排列组合,唯一的不同就是,质数需要呆在质数位上,非质数需要呆在非质数位上。
在明白了这一点之后就是进行排列组合,这就是数学方面的知识了,将质数的位数和非质数的位数进行排列组合计算出所有的情况。
排列组合的过程中需要注意,数有可能会溢出,但是题目也给了我们解决方案,只需要返回 模 mod 10^9 + 7 之后的结果就好了,所以我们每一次计算的时候可以先 模一次 mod 10^9 + 7 防止数据溢出。
排列组合的算法也很简单,比方说存在 k 个数,那么排列方式就有 k*(k-1)*(k-2)...1 种排列组合的方式。
那么根据这种排列组合的方式,就可以对质数和非质数的个数进行判断,能够有多少种排列方式
至于如何判断一个数是否是质数,这个方法应该是使用次数非常频繁的了,在这里就不多做解释了。
function numPrimeArrangements(n: number): number {
const MOD = 1000000007;
let primeCount = 0;
for(let i = 1; i <= n; i++){
if(isPrime(i)){
primeCount++;
}
}
let notPrimeCount = n - primeCount;
let result = 1;
for (let i = 2; i <= notPrimeCount; ++i) result = (result * i) % MOD;
for (let i = 2; i <= primeCount; ++i) result = (result * i) % MOD;
return result;
};
function isPrime(n: number): boolean {
if (n === 1) {
return false;
}
for (let i = 2; i * i <= n; i++) {
if (n % i === 0) {
return false;
}
}
return true;
}