个人解法
最开始的想法就是暴力
class Solution {
public:
int countOdds(int low, int high) {
int cnt = 0;
for(int i = low;i <= high;++i){
if(i&1==1)
cnt++;
}
return cnt;
}
}
然而超时
又想,区间端点的情况无非四种
- [奇,偶]
1 2 3 4 --> 4-1/2+1 - [奇,奇]
3 4 5 6 7 --> 7-3/2 +1 - [偶,偶]
2 3 4 5 6 --> 6-2/2 - [偶,奇]
2 3 4 5 --> 5-2/2+1
观察一下,可以看出来除了 [ 偶 , 偶 ] [偶,偶] [偶,偶] 是 h i g h − l o w 2 \frac{high-low}{2} 2high−low,其余三种情况都要+1,而这三种情况的共同点在于有一端是奇数,代码如下:
class Solution {
public:
int countOdds(int low, int high) {
int cnt = 0;
if(low & 1 == 1 || high &1 == 1)
cnt = 1;
cnt += (high-low)/2;
return cnt;
}
}
class Solution {
public:
int countOdds(int low, int high) {
int cnt=0;
if(low % 2==1 || high%2==1)
cnt=1;
cnt += (high-low)/2;
return cnt;
}
};
题解——前缀和
从0开始的区间 [ 0 , x ] [0,x] [0,x],其中奇数个数为 p r e ( x ) = x + 1 2 pre(x) = \frac{x+1}{2} pre(x)=2x+1 ,基于前缀和思想,区间 [ a , b ] [a,b] [a,b] 内的奇数个数为 p r e ( b ) − p r e ( a − 1 ) pre(b)-pre(a-1) pre(b)−pre(a−1)
class Solution {
public:
int pre(int x) {
return (x + 1) >> 1;
}
int countOdds(int low, int high) {
return pre(high) - pre(low - 1);
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/count-odd-numbers-in-an-interval-range/solution/zai-qu-jian-fan-wei-nei-tong-ji-qi-shu-shu-mu-by-l/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
收获
- 整数判断奇数:
x&1
按位与1,奇数则结果为1 - 整数除2:
x>>1
,左移1,相当于除2 - 前缀和思想:涉及到 区间 的问题,可以尝试转换为从同一起点开始的前缀 “相减”