File tree Expand file tree Collapse file tree 4 files changed +77
-4
lines changed
Expand file tree Collapse file tree 4 files changed +77
-4
lines changed Original file line number Diff line number Diff line change 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 )
Original file line number Diff line number Diff 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
Original file line number Diff line number Diff line change 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 >
Original file line number Diff line number Diff line change 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+ 解法二中空间换时间的思想在编程中经常用到。
You can’t perform that action at this time.
0 commit comments