leetcode周赛152-5173质数排列

题目描述:

  请你帮忙给从 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

解题思路:

  常规类型的题目,但是在统计质数个数的时候,在Math.sqrt处理下可能也会出现timeout limit ,因此,此处使用 厄拉多塞筛法 进行一定范围内的质数的统计,具体算法相见代码。

  同时,在进行mod操作时,mod操作具有交换律 (a*b*c)%m = a%m*b%m*c%m

掌握要点:

  质数统计算法 厄拉多塞筛法

  连乘中mod操作具有交换律

源码展示:

  

 1 public int numPrimeArrangements(int n) {
 2 
 3         if(n == 1 || n == 2){
 4             return 1;
 5         }
 6 
 7         //质数的个数
 8         boolean[] sign = new boolean[n + 1 ];
 9         int primes_count = 0;
10         for(int i = 2; i <= n;i++){
11             if(sign[i] == false){
12                 primes_count++;
13                 for(int j = i + i;j <= n; j += i){
14                     sign[j] = true;
15                 }
16             }
17         }
18 
19         //求阶乘
20         int no_primes_count = n - primes_count;
21         int max = Math.max(no_primes_count,primes_count);
22         int min = Math.min(no_primes_count,primes_count);
23 
24         //模运算复合交换律
25         long res = 1;
26         for(int i = 1;i <= max;i++){
27             res *= i;
28             res %= 1000000007;
29             if(i <= min){
30                 res *= i;
31                 res %= 1000000007;
32             }
33         }
34         return(int) res;
35 
36     }

猜你喜欢

转载自www.cnblogs.com/oldhands/p/11442614.html