倍数求和【LC2652】
给你一个正整数
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; } }-
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
-
从倍数出发
-
优化思路:借鉴埃氏筛
- [ 1 , n ] [1,n] [1,n]中有许多数不需要进行判断,我们可以从3、5、7的倍数出发,如果其在 [ 1 , n ] [1,n] [1,n]范围内,那么累加该数
- 在统计的过程中要避免重复统计,
3
∗
i
1
3*i_1
3∗i1、
5
∗
i
2
5*i_2
5∗i2和
7
∗
i
3
7*i_3
7∗i3可能指向同一个数
- 方法1:使用哈希表记录已经统计过的数
- 方法2:规定统计先后顺序,如果
i
i
i不能整除3,再判断
5
∗
i
5*i
5∗i是否在范围内;如果
i
i
i不能整除3和5,再判断
7
∗
i
7*i
7∗i是否在范围内
- 如果 i i i中包含因子3,那么对于 i ∗ 5 = j ∗ 3 ∗ 5 i*5=j*3*5 i∗5=j∗3∗5,在 i ′ = i / 3 ∗ 5 i'=i/3*5 i′=i/3∗5会统计该数
-
实现
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; } }-
复杂度分析
- 时间复杂度: O ( log n ) O(\log n) O(logn)
- 空间复杂度: O ( 1 ) O(1) O(1)
-
数学+容斥原理
-
思路
-
定义函数 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; } }-
复杂度分析
- 时间复杂度: O ( 1 ) O(1) O(1)
- 空间复杂度: O ( 1 ) O(1) O(1)
-

文章讨论了如何高效计算在给定范围[1,n]内能被3、5、7整除的整数之和,介绍了暴力枚举、埃氏筛优化和利用容斥原理的方法,最终给出了一种时间复杂度为O(logn)的解决方案。
3974

被折叠的 条评论
为什么被折叠?



