【编程能力】基本数据结构——leetcode 1523统计区间内奇数

这篇博客介绍了如何解决在一个给定区间内计算奇数个数的问题。作者首先尝试了暴力求解但导致超时,然后通过分析区间端点的四种情况,发现可以通过奇数端点来优化计算,只需加1并除以2即可得到结果。最后,作者引入了前缀和的思想,通过预先计算每个位置的奇数个数,进一步提高了算法效率。总结了整数判断奇数和除2的位运算技巧,并强调了在处理区间问题时可以考虑前缀和的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

个人解法

最开始的想法就是暴力

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. [奇,偶]
    1 2 3 4 --> 4-1/2+1
  2. [奇,奇]
    3 4 5 6 7 --> 7-3/2 +1
  3. [偶,偶]
    2 3 4 5 6 --> 6-2/2
  4. [偶,奇]
    2 3 4 5 --> 5-2/2+1

观察一下,可以看出来除了 [ 偶 , 偶 ] [偶,偶] [,] h i g h − l o w 2 \frac{high-low}{2} 2highlow,其余三种情况都要+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(a1)

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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

收获

  1. 整数判断奇数:x&1 按位与1,奇数则结果为1
  2. 整数除2:x>>1 ,左移1,相当于除2
  3. 前缀和思想:涉及到 区间 的问题,可以尝试转换为从同一起点开始的前缀 “相减”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AmosTian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值