普通视图
【Virtual World 03】上帝之手
vxe-gantt 甘特图实现产品进度列表,自定义任务条样式和提示信息
玩转小程序AR-实战篇
JavaScript 今天30 岁了,但连自己的名字都不属于自己
Vite8来啦,告别 esbuild + Rollup,Vite 8 统一用 Rolldown 了
每日一题-在区间范围内统计奇数数目🟢
给你两个非负整数 low 和 high 。请你返回 low 和 high 之间(包括二者)奇数的数目。
示例 1:
输入:low = 3, high = 7 输出:3 解释:3 到 7 之间奇数数字为 [3,5,7] 。
示例 2:
输入:low = 8, high = 10 输出:1 解释:8 到 10 之间奇数数字为 [9] 。
提示:
0 <= low <= high <= 10^9
O(1) 数学解(Python/Java/C++/C/Go/JS/Rust)
$[\textit{low},\textit{high}]$ 中的正奇数个数,等于 $[1,\textit{high}]$ 中的正奇数个数,减去 $[1,\textit{low}-1]$ 中的正奇数个数。(这个想法类似 前缀和)
正奇数可以表示为 $2k-1$,其中 $k$ 是正整数。
$[1,n]$ 中的正奇数满足 $1\le 2k-1\le n$,解得
$$
1\le k \le \left\lfloor\dfrac{n+1}{2}\right\rfloor
$$
这有 $\left\lfloor\dfrac{n+1}{2}\right\rfloor$ 个整数 $k$。
所以答案为
$$
\left\lfloor\dfrac{\textit{high}+1}{2}\right\rfloor - \left\lfloor\dfrac{\textit{low}}{2}\right\rfloor
$$
###py
class Solution:
def countOdds(self, low: int, high: int) -> int:
return (high + 1) // 2 - low // 2
###java
class Solution {
public int countOdds(int low, int high) {
return (high + 1) / 2 - low / 2;
}
}
###cpp
class Solution {
public:
int countOdds(int low, int high) {
return (high + 1) / 2 - low / 2;
}
};
###c
int countOdds(int low, int high) {
return (high + 1) / 2 - low / 2;
}
###go
func countOdds(low, high int) int {
return (high+1)/2 - low/2
}
###js
var countOdds = function(low, high) {
return Math.floor((high + 1) / 2) - Math.floor(low / 2);
};
###rust
impl Solution {
pub fn count_odds(low: i32, high: i32) -> i32 {
(high + 1) / 2 - low / 2
}
}
复杂度分析
- 时间复杂度:$\mathcal{O}(1)$。
- 空间复杂度:$\mathcal{O}(1)$。
思考题
- 计算 $[\textit{low},\textit{high}]$ 中每一位都是奇数的整数个数。
- 计算 $[\textit{low},\textit{high}]$ 中每一位都是奇数的整数之和。
欢迎在评论区分享你的思路/代码。
分类题单
- 滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
- 二分算法(二分答案/最小化最大值/最大化最小值/第K小)
- 单调栈(基础/矩形面积/贡献法/最小字典序)
- 网格图(DFS/BFS/综合应用)
- 位运算(基础/性质/拆位/试填/恒等式/思维)
- 图论算法(DFS/BFS/拓扑排序/基环树/最短路/最小生成树/网络流)
- 动态规划(入门/背包/划分/状态机/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
- 常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
- 数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
- 贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
- 链表、树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA)
- 字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)
欢迎关注 B站@灵茶山艾府
很显然【看不懂这个解释,建议退出这一行】
假设一个区间【0,3】,序列是0,1,2,3 奇数个数是3+1/2=2,区间【0,4】,序列是0,1,2,3,4 奇数个数4+1/2=2。
所以,所以,所以,high为3或者4,加个1,然后除以2,奇数个数都是2,然后,请自己推【0,5】和【0,6】,奇数个数都是3。
得出公式 high+1/2是区间【0,high】的奇数个数
因为low,左边界是可以改变的,所以先求【0,high】的奇数个数,然后在求【0,low】的奇数个数,然后做差得到总奇数个数。
注意,注意,注意,把+1看成右边区间增大,这里low是相当于在【0,high】里面的,你别加1,右边界high增大就行了。
**举个例子:**区间【3,7】,high的奇数个数 7+1/2=4,,如果此时3+1/2=2,4-2=2,答案就错了,要3/2=1,最后答案才等于3。
high+1奇数个数 - low奇数个数 **=**总奇数个数。
用公式表示 (high+1)/2 - low/2
int countOdds(int low, int high){
return ((high+1)/2)-((low)/2); //严谨
}
![]()
在区间范围内统计奇数数目
方法一:前缀和思想
思路与算法
如果我们暴力枚举 ${\rm [low, high]}$ 中的所有元素会超出时间限制。
我们可以使用前缀和思想来解决这个问题,定义 ${\rm pre}(x)$ 为区间 $[0, x]$ 中奇数的个数,很显然:
$${\rm pre}(x) = \lfloor \frac{x + 1}{2} \rfloor$$
故答案为 $\rm pre(high) - pre(low - 1)$。
代码
###C++
class Solution {
public:
int pre(int x) {
return (x + 1) >> 1;
}
int countOdds(int low, int high) {
return pre(high) - pre(low - 1);
}
};
###Java
class Solution {
public int countOdds(int low, int high) {
return pre(high) - pre(low - 1);
}
public int pre(int x) {
return (x + 1) >> 1;
}
}
###Python
class Solution:
def countOdds(self, low: int, high: int) -> int:
pre = lambda x: (x + 1) >> 1
return pre(high) - pre(low - 1)
###C#
public class Solution {
public int Pre(int x) {
return (x + 1) >> 1;
}
public int CountOdds(int low, int high) {
return Pre(high) - Pre(low - 1);
}
}
###Go
func pre(x int) int {
return (x + 1) >> 1
}
func countOdds(low int, high int) int {
return pre(high) - pre(low - 1)
}
###C
int pre(int x) {
return (x + 1) >> 1;
}
int countOdds(int low, int high) {
return pre(high) - pre(low - 1);
}
###JavaScript
var countOdds = function(low, high) {
return pre(high) - pre(low - 1);
};
function pre(x) {
return (x + 1) >> 1;
}
###TypeScript
function pre(x: number): number {
return (x + 1) >> 1;
}
function countOdds(low: number, high: number): number {
return pre(high) - pre(low - 1);
}
###Rust
impl Solution {
fn pre(x: i32) -> i32 {
(x + 1) >> 1
}
pub fn count_odds(low: i32, high: i32) -> i32 {
Self::pre(high) - Self::pre(low - 1)
}
}
复杂度分析
-
时间复杂度:$O(1)$。
-
空间复杂度:$O(1)$。