leetcode面试准备: CountPrimes

1 题目

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

接口:public int countPrimes(int n);

2 思路

统计小于n的素数个数,注意不包括n。

思路1:素数的判断

很容易想到素数的判断isPrime,然后逐个数来进行判断是否是素数。进行统计,输出结果。

复杂度: 把isPrime时间复杂度控制在O(n^0.5)的话,因此:Time:O(n^1.5) , Space:O(1)。
提交代码仍然超时。

思路2: 素数表

素数表的产生,在[1 to n)的范围内,标记出 非素数,剩下的就是素数了。
思路:

  1. 初始化所有的[2,n)都是素数
  2. 剔除掉 非素数
  3. 统计素数个数

如何标记 非素数呢?分组标记:

  • 2,[4,6,8,10,12,14,16,18,20,22,24...];
  • 3,[9,12,15,18,21,24,27,...];
  • 5,[25,30,35...]
  • 考虑一下终止条件

复杂度: Time: O(n log log n) , Space: O(n)

3 代码

思路1

	// 判断一个数是否是素数的方法:不是最好,但还可以。素数表是判断素数的好方法。
	// Time:O(sqrt(n)) Space:O(1)
	boolean isPrime(int n) {
		for (int i = 2; (i * i) <= n; i++) {
			if (n % i == 0)
				return false;
		}
		return true;
	}

	/**
	 * Solution 1: 逐个判断是否是素数,思路简单。但是超时
	 * Time:O(n^1.5) Space:O(1)
	 */
	public int countPrimes(int n) {
		int count = 0;
		for (int i = 2; i <= n; i++) {
			if(isPrime(i))  count++;
		}
		return count;
	}

思路2

	// Time: O(n log log n) Space: O(n)
	public int countPrimes(int n) {
		// 初始化所有的都是素数,在剔除掉 `非素数`
		boolean[] isPrime = new boolean[n];
		for (int i = 2; i < n; i++) {
			isPrime[i] = true;
		}
		
		// 剔除非素数
		for (int i = 2; (i * i) < n; i++){
			if (isPrime[i]) {
				for (int j = i * i; j < n; j += i) {
					isPrime[j] = false;
				}
			}
		}
		
		// 统计素数个数
		int count = 0;
		for (boolean is : isPrime) {
			if (is) count++;
		}
		return count;
	}

4 总结

素数是比较经典的题目。此题的tag: HashTable, Math

5 参考

posted on 2015-08-06 11:24  BYRHuangQiang  阅读(702)  评论(0编辑  收藏  举报

导航