在 [2, 3, .. n] 中找到最大的数,并且该数与 [2, 3, .. m] 中的所有数互质。


互质数是指除了 1 之外没有其他公因数的数。我们将给出两个数字 n 和 m。我们必须找到 2 到 n(包含 2 和 n)范围内的最大数,该数与 2 到 m(包含 2 和 m)范围内的所有元素互质。如果给定范围内没有元素与第二个范围内的所有元素互质,则我们必须返回或打印 -1。我们将实现该方法、代码,并讨论程序的时间和空间复杂度。

输入

N = 20, M = 13 

输出

19

解释

我们总共有从 2 到 20 的元素。

所有偶数的最小公因数为 2,这意味着 2、4、6、8、…、20 已被排除。

所有能被 2 到 M 范围内的素数整除的元素都被排除。

剩下的元素只有 17 和 19。所以,19 是结果。

输入

N = 10, M = 7

输出

-1

解释

如前所述,2 到 10 范围内的所有偶数都被剔除。所有能被 3、5 和 7 整除的元素都被剔除。这意味着 2 到 10 范围内的任何元素都不与 2 到 7 范围内的元素互质。

方法 1

在这种方法中,我们将找到所有素数或不被小于等于 m 的任何素数整除且大于 m 的数。我们将在这里使用埃拉托色尼筛法的概念,但以修改后的方式来查找不被小于 m 的素数整除的数。

示例

#include <iostream>
using namespace std;
// function to check if any number in ranges are co-prime 
int find(int n, int m){
   // creating array to store the result 
   int arr[n+1] = {0}; 
   for(int i = 2; i <= m; i++){
      // if the current number is not prime then continue
      if(arr[i] == 1){
         continue;
      }
      // current number is prime number mark all the numbers that are not prime and divible by current number
      for(int j = 2; i*j <= n; j++){
         arr[i*j] = 1;
      }
   }
   // finding the last number which is greater than m and is prime
   for(int i = n; i>m; i--){
      if(arr[i] == 0){
         return i;
      }
   }
   return -1;
}
int main(){
   int n = 20;
   int m = 13;
   // calling the function to print the largest element 
   cout<<"The largest number that is co-prime is: " << find(n,m)<<endl;
   return 0;
}

输出

The largest number that is co-prime is: 19

时间和空间复杂度

上述代码的时间复杂度等价于埃拉托色尼筛法,即 O(M*log(log(M)))。

上述代码的空间复杂度为 O(N),其中 N 是第一个范围。

方法 2

在这种方法中,我们将从 n 到 m(包含 n 但不包含 m)运行一个 for 循环,并且对于每个数字,我们将检查它们是否能被 2 到 m 的任何数字整除。

示例

#include <bits/stdc++.h>
using namespace std;
// function to check if the current number is divisible by any number in range 
bool isDivisble(int cur, int m){
   // getting square root of the current number 
   int sqr = sqrt(cur);
   // getting minimum of m and sqrt
   sqr = min(sqr,m);
   // checking divisblity 
   for(int i =2; i<= sqr; i++){
      if(cur%i == 0){
         return true;
      }
   }
   return false;
}
// function to check if any number in ranges are co-prime 
int find(int n, int m){
   // traversing over the given range from n to m 
   for(int i =n; i>m; i--){
      if(isDivisble(i, m)){
         continue;
      }
      else{
         return i;
      }
   }
   return -1;
}
int main(){
   int n = 10;
   int m = 7;
   // calling the function to print the largest element 
   cout<<"The largest number that is co-prime is: " << find(n,m)<<endl;
   return 0;
}

输出

The largest number that is co-prime is: -1

时间和空间复杂度

上述代码的时间复杂度等于 O(N*sqrt(N)),其中 sqrt(N) 是 N 的平方根。

上述代码的空间复杂度为 O(1),因为我们在这里没有使用任何额外的空间。

从上面给出的两个程序来看,两者根据其自身的规格都很好。第一个代码花费的时间较少,但空间复杂度较高,而第二个代码花费的时间更多,但空间复杂度较低。

如果 N 的值很高,则第二个代码是最好的,否则第一个代码是最好的。

如果对于固定的 m 对 n 进行范围查询,则第一个代码是最好的。

结论

在本教程中,我们实现了一个程序来查找第一个 n 个元素中最大的数,该数与前 m 个元素中的所有元素互质,其中 1 在两个范围内都不包含。互质数是指除了 1 之外没有其他公因数的数。我们实现了一种方法,它是埃拉托色尼筛法的修改版本,时间复杂度为 O(M*log(log(M))),空间复杂度为 O(N),以及另一种具有常数空间复杂度的方案。

更新于: 2023-09-01

87 次查看

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告