如何高效计算范围内奇数的个数?
题目来自力扣
:1523. 在区间范围内统计奇数数目
注:所有实例都是按照0-1000000000的范围进行的
1、普通版
public int countOdds(int low, int high) {
int count = 0;
for(int i=low;i<=high;i++) {
if(i%2!=0) {
count++;
}
}
return count;
}
运行时间:845ms
普普通通的计算方式,朴实无华
2、普通版+位运算
int count = 0;
for(int i=low;i<=high;i++) {
if((i & 1) == 1) {
count++;
}
}
return count;
运算时间:782ms
看图可知,奇数的二进制最低位都是为1,偶数二进制最低位都为0
二进制位比较 &运算中1&1=1,1&0=0,0&0=0
3、Stream版
基于普通版,使用Stream流就会更快一些了
public int countOdds(int low, int high) {
return (int) IntStream.rangeClosed(low, high)
.filter(e -> e % 2 != 0)
.count();
}
运行时间:942ms
4、Stream+并行
加上parallel()
就好了,速度比之前的普通Stream还要快
public int countOdds(int low, int high) {
return (int) IntStream.rangeClosed(low, high)
.parallel()
.filter(e -> e % 2 != 0)
.count();
}
运行时间:266ms
5、Stream + 并行 + 位运算
public int countOdds(int low, int high) {
return (int) IntStream.rangeClosed(low, high)
.parallel()
.filter(e -> (e & 1) == 1)
.count();
}
运行时间:144ms
6、开拓思路版(极速版)
public int countOdds(int low, int high) {
return ((high + 1) >> 1) - (low >> 1);
}
运行时间:0ms
这一种方式已经不再是普通的过滤计算了,更像是给个公式,然后套值计算
这里利用到了奇偶数的出现规律
范围 | 算式 |
---|---|
0 - 10 | (10+1) / 2 - 0 / 2 = 5 |
3 - 7 | (7+1) / 2 - 3 / 2 = 3 |
…… | …… |
其后得出,区间范围奇数个数计算公式:
在(min,max]范围内奇数的个数为:(max+1)/2 - min/2