You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现Total Primes计数超时,请求算法优化

Optimizing "Total Primes" Calculation for Large Ranges (Up to 10^7)

Your core logic works for small test cases, but when scaling up to 10^7, the naive per-number checks are way too slow—let's fix that with two key optimizations that'll cut down the workload drastically:

1. Prioritize Digit Filtering First

Instead of checking every number in [a,b) for primality AND digit validity, only generate numbers that already have all prime digits (2, 3, 5, 7) first. These numbers are far fewer than the full range: for numbers up to 10^7, there are only ~21k such numbers total. That's a massive reduction from 10 million iterations!

We can generate these numbers iteratively, building them digit by digit to avoid wasting time on invalid candidates.

2. Use Sieve of Eratosthenes for O(1) Primality Checks

The naive isPrime function runs in O(√n) time per number, which adds up fast. Precomputing a sieve of primes up to 10^7 lets us check if a number is prime in constant time. A sieve for 10^7 only takes ~10MB of memory (using a boolean array), which is totally manageable.

Putting It All Together

Here's the optimized code:

def sieve(max_limit):
    if max_limit < 2:
        return []
    # Initialize sieve: True means the number is prime
    is_prime = [True] * max_limit
    is_prime[0] = is_prime[1] = False
    for i in range(2, int(max_limit ** 0.5) + 1):
        if is_prime[i]:
            # Mark all multiples of i as non-prime
            is_prime[i*i : max_limit : i] = [False] * len(is_prime[i*i : max_limit : i])
    return is_prime

def generate_valid_digit_numbers(a, b):
    valid_digits = [2, 3, 5, 7]
    numbers = []
    # Start with 1-digit valid numbers
    for d in valid_digits:
        if a <= d < b:
            numbers.append(d)
    # Build longer numbers by appending valid digits
    current_numbers = numbers.copy()
    while current_numbers:
        next_batch = []
        for num in current_numbers:
            for d in valid_digits:
                new_num = num * 10 + d
                if new_num >= b:
                    continue
                if new_num >= a:
                    next_batch.append(new_num)
        numbers.extend(next_batch)
        current_numbers = next_batch
    return numbers

def get_total_primes(a, b):
    if b <= 2:
        return 0
    # Generate sieve up to the upper bound of the range
    prime_sieve = sieve(b)
    # Get all numbers in [a,b) with all prime digits
    valid_numbers = generate_valid_digit_numbers(a, b)
    # Count how many valid numbers are primes
    return sum(1 for num in valid_numbers if prime_sieve[num])

Why This Works So Much Faster

  • Sieve Precomputation: The sieve runs in O(n log log n) time, which for n=10^7 completes in a fraction of a second.
  • Reduced Iterations: Instead of looping through 10 million numbers, we only check ~21k pre-filtered candidates that already pass the digit test.
  • O(1) Primality Checks: Each valid number's primality is verified instantly using the precomputed sieve.

Testing this with your sample inputs:

  • get_total_primes(10, 100) returns 4 (matches your expected result)
  • get_total_primes(500, 600) returns 3 (also matches)

For large ranges up to 10^7, this will run well under the 12-second time limit.

内容的提问来源于stack exchange,提问作者ndogac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:43:11