2652. 倍数求和
1.题目介绍
2.题解
2.1 枚举
思路
直接从[1,n]进行一次遍历,判断出能被整除的数便加到一个变量result中
代码
class Solution {
public:
int sumOfMultiples(int n) {
int result = 0;
for (int i = 1; i <=n; i++)
if (i % 3 == 0 || i % 5 == 0 || i % 7 == 0)
result += i;
return result;
}
};
代价
时间复杂度:O(n)。
空间复杂度:O(1)。
2.2 容斥原理
思路
找到所有能被3整除的数并求和,同理分别找到所有能被5,7整除的数并求和;这里就会存在一个问题,重复求和了同时能被3,5,7其中两个或三个整除的数,需要减除重复的
综合一下分析,考虑在区间 [1,n]内能被数 m 整除的整数,从小到大排序后成为一个等差数列,和为:\(f(n,m)=\frac{(m+m\times\lfloor\frac nm\rfloor)\times\lfloor\frac nm\rfloor}2\)
根据 容斥原理,在区间 [1,n] 内,能被 3、5和 7 整除的整数之和为:\(f(n,3)+f(n,5)+f(n,7)-f(n,3\times5)-f(n,3\times7)-f(n,5\times7)+f(n,3\times5\times7)\)
代码
class Solution {
public:
int sumOfMultiples(int n) {
int result = 0;
return sumDividerNum(n,3) + sumDividerNum(n,5) + sumDividerNum(n,7) - sumDividerNum(n,3*5) - sumDividerNum(n,3*7) - sumDividerNum(n,5*7) + sumDividerNum(n, 3*5*7);
}
int sumDividerNum(int n, int m){
return (m+m*(n/m))*(n/m)/2;
}
};
代价
时间复杂度:O(1)。
空间复杂度:O(1)。