请你帮忙给从 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
提示:
方法一:质数判断 + 组合数学 思路
求符合条件的方案数,使得所有质数都放在质数索引上,所有合数放在合数索引上,质数放置和合数放置是相互独立的,总的方案数即为「所有质数都放在质数索引上的方案数」\times「所有合数都放在合数索引上的方案数」。求「所有质数都放在质数索引上的方案数」,即求质数个数 numPrimes 的阶乘。「所有合数都放在合数索引上的方案数」同理。求质数个数时,可以使用试除法。「204.计数质数的官方题解 」列举了更多的求质数个数方法,读者可以根据兴趣阅读。最后注意计算过程中需要对 10^9+7 取模。
代码
[sol1-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution : def numPrimeArrangements (self, n: int ) -> int : numPrimes = sum (self.isPrime(i) for i in range (1 , n + 1 )) return self.factorial(numPrimes) * self.factorial(n - numPrimes) % (10 ** 9 + 7 ) def isPrime (self, n: int ) -> int : if n == 1 : return 0 for i in range (2 , int (sqrt(n)) + 1 ): if n % i == 0 : return 0 return 1 def factorial (self, n: int ) -> int : res = 1 for i in range (1 , n + 1 ): res *= i res %= (10 ** 9 + 7 ) return res
[sol1-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { static final int MOD = 1000000007 ; public int numPrimeArrangements (int n) { int numPrimes = 0 ; for (int i = 1 ; i <= n; i++) { if (isPrime(i)) { numPrimes++; } } return (int ) (factorial(numPrimes) * factorial(n - numPrimes) % MOD); } public boolean isPrime (int n) { if (n == 1 ) { return false ; } for (int i = 2 ; i * i <= n; i++) { if (n % i == 0 ) { return false ; } } return true ; } public long factorial (int n) { long res = 1 ; for (int i = 1 ; i <= n; i++) { res *= i; res %= MOD; } return res; } }
[sol1-C#] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class Solution { const int MOD = 1000000007 ; public int NumPrimeArrangements (int n ) { int numPrimes = 0 ; for (int i = 1 ; i <= n; i++) { if (IsPrime(i)) { numPrimes++; } } return (int ) (Factorial(numPrimes) * Factorial(n - numPrimes) % MOD); } public bool IsPrime (int n ) { if (n == 1 ) { return false ; } for (int i = 2 ; i * i <= n; i++) { if (n % i == 0 ) { return false ; } } return true ; } public long Factorial (int n ) { long res = 1 ; for (int i = 1 ; i <= n; i++) { res *= i; res %= MOD; } return res; } }
[sol1-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 const int MOD = 1e9 + 7 ;class Solution {public : int numPrimeArrangements (int n) { int numPrimes = 0 ; for (int i = 1 ; i <= n; i++) { if (isPrime (i)) { numPrimes++; } } return (int ) (factorial (numPrimes) * factorial (n - numPrimes) % MOD); } bool isPrime (int n) { if (n == 1 ) { return false ; } for (int i = 2 ; i * i <= n; i++) { if (n % i == 0 ) { return false ; } } return true ; } long factorial (int n) { long res = 1 ; for (int i = 1 ; i <= n; i++) { res *= i; res %= MOD; } return res; } };
[sol1-C] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #define MOD 1000000007 bool isPrime (int n) { if (n == 1 ) { return false ; } for (int i = 2 ; i * i <= n; i++) { if (n % i == 0 ) { return false ; } } return true ; } long factorial (int n) { long res = 1 ; for (int i = 1 ; i <= n; i++) { res *= i; res %= MOD; } return res; } int numPrimeArrangements (int n) { int numPrimes = 0 ; for (int i = 1 ; i <= n; i++) { if (isPrime(i)) { numPrimes++; } } return (int ) (factorial(numPrimes) * factorial(n - numPrimes) % MOD); }
[sol1-Golang] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 const mod int = 1e9 + 7 func numPrimeArrangements (n int ) int { numPrimes := 0 for i := 2 ; i <= n; i++ { if isPrime(i) { numPrimes++ } } return factorial(numPrimes) * factorial(n-numPrimes) % mod } func isPrime (n int ) bool { for i := 2 ; i*i <= n; i++ { if n%i == 0 { return false } } return true } func factorial (n int ) int { f := 1 for i := 1 ; i <= n; i++ { f = f * i % mod } return f }
[sol1-JavaScript] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 const MOD = 1000000007 ;var numPrimeArrangements = function (n ) { let numPrimes = 0 ; for (let i = 2 ; i <= n ; i++) { if (isPrime (i)) { numPrimes++; } } let res = 1 ; let m = n - numPrimes; while (numPrimes > 0 ) { res = res % MOD ; res *= numPrimes; numPrimes--; } while (m > 0 ) { res = res % MOD ; res *= m; m--; } return res; }; const isPrime = (n ) => { if (n === 1 ) { return false ; } for (let i = 2 ; i * i <= n; i++) { if (n % i === 0 ) { return false ; } } return true ; }
复杂度分析