【leetcode】204 - Count Primes

Description:Count the number of prime numbers less than a non-negative number, n.

Hint:

    1. Let‘s start with a isPrime function. To determine if a number is prime, we need to check if it is not divisible by any number less than n. The runtime complexity ofisPrime function would be O(n) and hence counting the total prime numbers up to n would be O(n2). Could we do better?
    2. As we know the number must not be divisible by any number > n / 2, we can immediately cut the total iterations half by dividing only up to n / 2. Could we still do better?
    3. Let‘s write down all of 12‘s factors:
      2 × 6 = 12
      3 × 4 = 12
      4 × 3 = 12
      6 × 2 = 12
      

      As you can see, calculations of 4 × 3 and 6 × 2 are not necessary. Therefore, we only need to consider factors up to √n because, if n is divisible by some number p, then n = p × q and since p ≤ q, we could derive that p ≤ √n.

      Our total runtime has now improved to O(n1.5), which is slightly better. Is there a faster approach?

      public int countPrimes(int n) {
         int count = 0;
         for (int i = 1; i < n; i++) {
            if (isPrime(i)) count++;
         }
         return count;
      }
      
      private boolean isPrime(int num) {
         if (num <= 1) return false;
         // Loop‘s ending condition is i * i <= num instead of i <= sqrt(num)
         // to avoid repeatedly calling an expensive function sqrt().
         for (int i = 2; i * i <= num; i++) {
            if (num % i == 0) return false;
         }
         return true;
      }
      
    4. The Sieve of Eratosthenes is one of the most efficient ways to find all prime numbers up to n. But don‘t let that name scare you, I promise that the concept is surprisingly simple.


      Sieve of Eratosthenes: algorithm steps for primes below 121. "Sieve of Eratosthenes Animation" by SKopp is licensed under CC BY 2.0.

      We start off with a table of n numbers. Let‘s look at the first number, 2. We know all multiples of 2 must not be primes, so we mark them off as non-primes. Then we look at the next number, 3. Similarly, all multiples of 3 such as 3 × 2 = 6, 3 × 3 = 9, ... must not be primes, so we mark them off as well. Now we look at the next number, 4, which was already marked off. What does this tell you? Should you mark off all multiples of 4 as well?

    5. 4 is not a prime because it is divisible by 2, which means all multiples of 4 must also be divisible by 2 and were already marked off. So we can skip 4 immediately and go to the next number, 5. Now, all multiples of 5 such as 5 × 2 = 10, 5 × 3 = 15, 5 × 4 = 20, 5 × 5 = 25, ... can be marked off. There is a slight optimization here, we do not need to start from 5 × 2 = 10. Where should we start marking off?
    6. In fact, we can mark off multiples of 5 starting at 5 × 5 = 25, because 5 × 2 = 10 was already marked off by multiple of 2, similarly 5 × 3 = 15 was already marked off by multiple of 3. Therefore, if the current number is p, we can always mark off multiples of p starting at p2, then in increments of pp2 + pp2 + 2p, ... Now what should be the terminating loop condition?
    7. It is easy to say that the terminating loop condition is p < n, which is certainly correct but not efficient. Do you still remember Hint #3?
    8. Yes, the terminating loop condition can be p < √n, as all non-primes ≥ √n must have already been marked off. When the loop terminates, all the numbers in the table that are non-marked are prime.
 1 class Solution {
 2 public:
 3
 4     int countPrimes(int n) {
 5         if(n<=2)return 0;
 6         int count=0;
 7         vector<bool> isPrime(n,true);
 8
 9         for(int i=2;i<n;i++){
10             if(isPrime[i]){
11                 count++;
12                 for(long long j=(long long)i*i;j<n;j+=i)    //两个longlong必不可少,否则会运行时错误,当i很大时,i*i超出int范围
13                     isPrime[(int)j]=false;
14             }
15         }
16         return count;
17     }
18
19 };
时间: 2024-10-12 21:12:10

【leetcode】204 - Count Primes的相关文章

【LeetCode】204. Count Primes 解题小结

题目: Description: Count the number of prime numbers less than a non-negative number, n. 这个题目有提示,计算素数的方法应该不用多说. class Solution { public: int countPrimes(int n) { vector<bool> isPrime; for (int i = 0; i < n; ++i){ isPrime.push_back(true); } for (int

【leetcode】357. Count Numbers with Unique Digits

题目描述: Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. 解题分析: 题目要就就是找出 0≤ x < 10n中各位数字都不相同的数的个数.要接触这道题只需要理解: 1.设f(n)表示n为数字中各位都不相同的个数,则有countNumbersWithUniqueDigits(n)=f(1)+f(2)+……+f(n)=f(n)+countNumbersWithU

【LeetCode】327. Count of Range Sum

题目: Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive. Range sum S(i, j) is defined as the sum of the elements in nums between indices i and  j (i ≤ j), inclusive. Note: A naive algorithm of O(n2) is tr

【LeetCode】222. Count Complete Tree Nodes

Count Complete Tree Nodes Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from Wikipedia:In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last le

【LeetCode】222. Count Complete Tree Nodes-完全二叉树的结点个数

一.描述: 二.思路: 完全二叉树: 对于整棵二叉树,从根结点出发,一直沿左下方向遍历树的深度是l,一直沿右下方向遍历的深度是r:则有两种情况: 1.l == r,左右深度相等,一定是完全二叉树,即满二叉树,结点个数为(2^l-1)或(2^r-1): 2.l != r,只有一种情况:在二叉树的倒数第二层,某个父结点只有左叶子结点而无右叶子结点,及l=r+1.等价的说,将这一个多余的左叶子结点去掉的话,则每棵最小的二叉树(一共3个结点)都是满二叉树,即又回到了上述情况1,最后再加1即为总叶子结点:

【Leetcode】38. Count and Say

Question: The count-and-say sequence is the sequence of integers with the first five terms as following: 1. 1 2. 11 3. 21 4. 1211 5. 111221 1 is read off as "one 1" or 11. 11 is read off as "two 1s" or 21. 21 is read off as "one 2

【leetcode】1395. Count Number of Teams

题目如下: There are n soldiers standing in a line. Each soldier is assigned a unique rating value. You have to form a team of 3 soldiers amongst them under the following rules: Choose 3 soldiers with index (i, j, k) with rating (rating[i], rating[j], rat

【leetcode】Minimum Window Substring

问题: 给定两个字符串,S,T,返回S中包含T中所有字符的最短的字串,若不存在,则返回"".时间复杂度为O(n). 例如:S = "ADOBCODEBANC" T = "ABC" 返回BANC 生活场景: 把问题具体化现实化一点.有n层楼,每层楼里放有一个物品,现在老板给你一个物品清单,里面是要你集齐的物品,你可以乘坐电梯,但是电梯只停一次,停在哪一层,就从哪一层开始向楼上搜集物品,至于要在那层停电梯,由你自己选择. 这里我们当然选择即能集齐物品

【LeetCode】Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example,Given [100, 4, 200, 1, 3, 2],The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should run in