【问题标题】:Find maximum occurrence digit in a range of prime numbers在素数范围内查找最大出现位数
【发布时间】:2015-09-28 12:34:03
【问题描述】:

给定两个数字 a 和 b (1

示例:从 1 到 20,质数为 - 2、3、5、7、11、13、17、19。这里 2、5、9 只出现一次,3、7 出现两次,1 出现 5次。所以结果是 1。

一种基本方法是:

  • 在 [a, b] 范围内 - 查找所有素数。
  • 取一个计数数组来计算从 0 到 9 的出现次数。
  • 对于范围内的所有素数,提取所有数字并相应地增加计数数组中数字的计数。
  • 从计数数组中找出最大值。

但这对于大范围(例如 [1, 1000000])来说效率很低。

有没有什么有效的方法可以做到这一点?

【问题讨论】:

  • 我认为你不能做得更好。
  • @Henry 不是针对单个查询。但是,如果有多个这样的查询,可以通过预计算来改进幼稚的方法
  • 你的基本方法在什么意义上是“低效的”?

标签: arrays algorithm numbers primes


【解决方案1】:

执行sieve of Eratosthenes 以查找范围 0、106 中的所有素数。这可以很快完成(在普通机器上不到 1 秒)。使用 10 个辅助数组 - 每个数组的每个数字一个,大小为 106。如果一个数字不是素数,则 0 存储所有 10 个数组。如果一个数字是素数,则在每个数组中存储给定数字在该数字中出现的次数。之后循环遍历每个数组并累积给定数字出现次数的prefix sums。这可以很容易地在线性时间内完成。说数字 3:

for (int i = 1; i < n; ++i) {
   a3[i] += a3[i-1];
}

拥有这些数组,您可以在恒定时间内计算每个数字在指定时间间隔内出现的次数。即区间[x,y]中出现3的次数为a3[y] - a3[x-1](注意x为0时的特殊情况)。

该算法的计算复杂度与预计算的埃拉托色尼筛法和每个查询的常数相同。内存复杂度是线性的。您可以通过仅将素数的值存储在辅助数组中来改善内存开销,从而使它们的大小等于素数的数量,如果需要,最多可达 106。但是,这会使实现稍微复杂一些。

【讨论】:

  • 我看不出有 10 个数组 长度为 10**6 的意义。只需将一个长度为 10 的数组初始化为全零,每个条目表示该数字出现的次数。然后通过所有素数就足以计算计数。
【解决方案2】:
function writeOutput(left, right) {

let digitCount = new Array(10);
digitCount.fill(0)


for(let num = left ; num <= right; num++){
    if(isPrime(num)){
        let copyNum = num;
        while (copyNum > 0){
            let d = copyNum % 10;
            digitCount[d]++;
            copyNum = copyNum / 10;
        }
    }
}


 let maxCount = 0;

 let maxNum = 0;

 for (let j = 0; j < digitCount.length; j++){
   if(digitCount[j] > maxCount){
    maxCount = digitCount[j];
    maxNum = j;
   }
 }
if(maxCount == 1){
    for(let k = digitCount.length - 1; k > 0; k--){
      if(digitCount[k] > 0){
        maxNum = k;
        break;
       }
    }
  } else if( maxCount > 1){
    return maxNum;
 } else {
    maxNum = -1;
 }

 return maxNum

 }
   function isPrime(n){
      for(let i = 2; i * i <= n; i++){
         if(n % i == 0){
           return false
         }
     }
     return true
  }

【讨论】:

  • 尽管您的代码可能对作者有所帮助,但提倡您的解决方案是一种很好的做法。
  • 什么意思?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 2021-11-13
  • 2015-03-04
  • 1970-01-01
相关资源
最近更新 更多