给你一个正整数
n,请你计算在[1,n]范围内能被3、5、7整除的所有整数之和。返回一个整数,用于表示给定范围内所有满足约束条件的数字之和。
思路
枚举
[
1
,
n
]
[1,n]
[1,n]范围内每个数,判断是否能被 3、5、7 整除,如果能则累加结果
实现
class Solution {
public int sumOfMultiples(int n) {
int res = 0;
for (int i = 1; i <= n; i++){
if (i % 3 == 0 || i % 5 == 0 || i % 7 == 0){
res += i;
}
}
return res;
}
}
优化思路:借鉴埃氏筛
实现
class Solution {
public int sumOfMultiples(int n) {
int res = 0;
int i = 1;
while (i * 3 <= n){
res += i * 3;
// 避免重复计算 如果i中包含因子3,那么i*5=j*3*5,在i'=i/3*5会统计该数
if (i % 3 != 0){
if (i * 5 <= n){
res += i * 5;
}
if (i % 5 != 0 && i * 7 <= n){
res += i * 7;
}
}
// if (i % 3 != 0 && i * 5 <= n){
// res += i * 5;
// }
// if (i % 3 != 0 && i % 5 != 0 && i * 7 <= n){
// res += i * 7;
// }
i++;
}
return res;
}
}
复杂度分析
思路
定义函数
f
(
x
,
n
)
f(x,n)
f(x,n)为
[
1
,
n
]
[1,n]
[1,n]中能被
x
x
x整除的数之和,那么一共有
m
=
⌊
n
/
x
⌋
m=\lfloor n/x \rfloor
m=⌊n/x⌋个数能被
x
x
x整数,组成首项为
x
x
x、末项为
x
m
xm
xm的等差数列,和为
f
(
x
)
=
(
x
+
m
x
)
∗
m
2
f(x)=\frac {(x+mx)*m}{2}
f(x)=2(x+mx)∗m
根据容斥原理,能被 3、5、7 整除的所有数之和为
f
(
3
,
n
)
+
f
(
5
,
n
)
+
f
(
7
,
n
)
−
f
(
3
∗
5
,
n
)
−
f
(
3
∗
7
,
n
)
−
f
(
5
∗
7
,
n
)
+
f
(
3
∗
5
∗
7
,
n
)
;
f(3,n) + f(5,n) + f(7,n) - f(3*5,n) - f(3*7,n) - f(5*7,n) + f(3*5*7,n);
f(3,n)+f(5,n)+f(7,n)−f(3∗5,n)−f(3∗7,n)−f(5∗7,n)+f(3∗5∗7,n);
实现
class Solution {
public int sumOfMultiples(int n) {
return f(3,n) + f(5,n) + f(7,n) - f(3*5,n) - f(3*7,n) - f(5*7,n) + f(3*5*7,n);
}
public int f(int x, int n){
int m = n / x;
return (x + m * x) * m / 2;
}
}
复杂度分析