Skip to content

Commit 37c6018

Browse files
committed
204
1 parent a670e04 commit 37c6018

File tree

4 files changed

+77
-4
lines changed

4 files changed

+77
-4
lines changed

SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,5 @@
182182
* [201 题到 300 题](leetcode-201-300.md)
183183
* [201. Bitwise AND of Numbers Range](leetcode-201-Bitwise-AND-of-Numbers-Range.md)
184184
* [202. Happy Number](leetcode-202-Happy-Number.md)
185-
* [203. Remove Linked List Elements](leetcode-203-Remove-Linked-List-Elements.md)
185+
* [203. Remove Linked List Elements](leetcode-203-Remove-Linked-List-Elements.md)
186+
* [204. Count Primes](leetcode-204-Count-Primes.md)

leetcode-108-Convert-Sorted-Array-to-Binary-Search-Tree.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,9 @@ int mid = (start + end) >>> 1
245245

246246
首先大家可以补一下 [补码](https://mp.weixin.qq.com/s/uvcQHJi6AXhPDJL-6JWUkw) 的知识。
247247

248-
其实问题的关键就是这里了`>>>` ,我们知道还有一种右移是`>>`。区别在于`>>`为有符号右移,右移以后最高位保持原来的最高位。而`>>>`这个右移的话最高位补 0
248+
其实问题的关键就是这里了`>>>` ,我们知道还有一种右移是`>>`。区别在于`>>`为有符号右移,右移以后最高位保持原来的最高位。而 `>>>` 这个右移的话最高位补 0
249249

250-
所以这里其实利用到了整数的补码形式,最高位其实是符号位,所以当 `start + end`溢出的时候,其实本质上只是符号位收到了进位,而`>>>`这个右移可以带着符号位右移,所以之前的信息没有丢掉
250+
所以这里其实利用到了整数的补码形式,最高位其实是符号位,所以当 `start + end` 溢出的时候,其实本质上只是符号位收到了进位,而`>>>`这个右移不仅可以把符号位右移,同时最高位只是补零,不会对数字的大小造成影响
251251

252252
但`>>`有符号右移就会出现问题了,事实上 JDK6 之前都用的`>>`,这个 BUG 在 java 里竟然隐藏了十年之久。
253253

leetcode-201-300.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@
44

55
<a href="leetcode-202-Happy-Number.html">202. Happy Number</a>
66

7-
<a href="leetcode-203-Remove-Linked-List-Elements.html">203. Remove Linked List Elements</a>
7+
<a href="leetcode-203-Remove-Linked-List-Elements.html">203. Remove Linked List Elements</a>
8+
9+
<a href="leetcode-204-Count-Primes.html">204. Count Primes</a>

leetcode-204-Count-Primes.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# 题目描述(简单难度)
2+
3+
![](https://windliang.oss-cn-beijing.aliyuncs.com/204.jpg)
4+
5+
求出小于 `n` 的素数个数。
6+
7+
# 解法一
8+
9+
遍历 `2``n - 1` ,依次判断当前数是否是素数。
10+
11+
判断 `n` 是否是素数,只需要判断 `2``n - 1` 是否是 `n` 的因子,如果有一个是,那就表明 `n` 不是素数。
12+
13+
判断素数可以做一个优化,那就是不需要判断 `2``n - 1`,只需要判断`2``sqrt(n)` 也就是根号 `n` 即可。因为如果存在超过根号 `n` 的因子,那么一定存在小于根号 `n` 的数与之对应。
14+
15+
```java
16+
public int countPrimes(int n) {
17+
int count = 0;
18+
for (int i = 2; i < n; i++) {
19+
if (isPrime(i)) {
20+
count++;
21+
}
22+
}
23+
return count;
24+
}
25+
26+
private boolean isPrime(int n) {
27+
int sqrt = (int) Math.sqrt(n);
28+
for (int i = 2; i <= sqrt; i++) {
29+
if (n % i == 0) {
30+
return false;
31+
}
32+
}
33+
return true;
34+
}
35+
```
36+
37+
# 解法二
38+
39+
空间换时间,参考 [这里](https://leetcode.com/problems/count-primes/discuss/57588/My-simple-Java-solution)
40+
41+
用一个数组表示当前数是否是素数。
42+
43+
然后从 `2` 开始,将 `2` 的倍数,`4``6``8``10` ...依次标记为非素数。
44+
45+
下个素数 `3`,将 `3` 的倍数,`6``9``12``15` ...依次标记为非素数。
46+
47+
下个素数 `7`,将 `7` 的倍数,`14``21``28``35` ...依次标记为非素数。
48+
49+
在代码中,因为数组默认值是 `false` ,所以用 `false` 代表当前数是素数,用 `true` 代表当前数是非素数。
50+
51+
```java
52+
public int countPrimes(int n) {
53+
boolean[] notPrime = new boolean[n];
54+
int count = 0;
55+
for (int i = 2; i < n; i++) {
56+
if (!notPrime[i]) {
57+
count++;
58+
//将当前素数的倍数依次标记为非素数
59+
for (int j = 2; j * i < n; j++) {
60+
notPrime[j * i] = true;
61+
}
62+
}
63+
}
64+
return count;
65+
}
66+
```
67+
68+
#
69+
70+
解法二中空间换时间的思想在编程中经常用到。

0 commit comments

Comments
 (0)