2652. 倍数求和

2652. 倍数求和

    • 题目
    • 方法-【枚举】 & 题目特征-【求计算在给定范围内满足某种条件的整数之和】
    • 方法-【容斥原理】 & 题目特征-【计算满足多个条件的元素之和,并且需要避免重复计数】

题目

题目链接:https://leetcode.cn/problems/sum-multiples/description/

给你一个正整数 n ,请你计算在 [1,n] 范围内能被 3、5、7 整除的所有整数之和。

返回一个整数,用于表示给定范围内所有满足约束条件的数字之和。

方法-【枚举】 & 题目特征-【求计算在给定范围内满足某种条件的整数之和】

class Solution {
public:
    int sumOfMultiples(int n) {
        int sum = 0;
        for (int i = 1; i <= n; i++) 
            if (i % 3 == 0 || i % 5 == 0 || i % 7 == 0) 
                sum += i;
        return sum;
    }
};

方法-【容斥原理】 & 题目特征-【计算满足多个条件的元素之和,并且需要避免重复计数】

举个例子,当我们想要计算一共有多少只动物,但有些动物同时属于几个类别,我们可以使用容斥原理。

假设我们有三个类别的动物:猫、狗和兔子,并且我们有以下信息:

  • 喜欢猫的人数10
  • 喜欢狗的人数15
  • 喜欢兔子的人数8

我们想要找到同时喜欢三种动物的人数。

如果我们简单地将每个类别的动物数量相加,我们会得到10 + 15 + 8 = 33只动物。但这样计算会有重复计数的问题,因为有些动物同时属于多个类别。

为了避免重复计数,我们可以使用容斥原理。根据容斥原理,我们需要:

  • 将每个类别的动物数量相加;
  • 减去同时属于两个类别的动物数量;
  • 加上同时属于三个类别的动物数量。

因此,我们可以计算:10 + 15 + 8 - (猫 & 狗的数量) - (狗 & 兔子的数量) - (猫 & 狗 & 兔子的数量) = 1只动物。

通过应用容斥原理,我们得到了正确的结果,即一共有1只动物,避免了重复计数的问题。

这个题目和答案是乱写的,主要看题目特征和方法的匹配 — 之所以使用 xx方法(容斥原理),是因为题目有 xx 特征。

在 2652 这题:

  • 集合 A:能被 2 整除的数;
  • 集合 B:能被 3 整除的数;
  • 集合 C:能被 5 整除的数。

我们希望计算在给定范围内满足这些条件的数的总数,同时避免重复计数。

那我们需要容斥原理才能做到全面完整、不重不漏的计数。

具体看官网题解:

f(n, m) 表示在区间 [1, n] 内能被 m 整除的整数之和。

f(n, m) 函数计算方法:

class Solution {
private: 
    int f(int n, int k){
        int cnt = n / k;                  // cnt * k 为小于等于n的最大数字
        return (k + cnt * k) * cnt / 2;   // 等差数列求和公式
    }
public:
    int sumOfMultiples(int n) {
        return f(n, 3) + f(n, 5) + f(n, 7) - f(n, 3*5) - f(n, 3 * 7) - f(n,5*7) + f(n, 3 * 5 * 7);
    }
};

或者

class Solution {
public:
    int sumOfMultiples(int n) {
        int sum = 0;
        int div3 = n / 3;
        int div5 = n / 5;
        int div7 = n / 7;
        int div15 = n / 15;
        int div21 = n / 21;
        int div35 = n / 35;
        int div105 = n / 105;

        sum = 3 * div3 * (div3 + 1) / 2
            + 5 * div5 * (div5 + 1) / 2
            + 7 * div7 * (div7 + 1) / 2
            - 15 * div15 * (div15 + 1) / 2
            - 21 * div21 * (div21 + 1) / 2
            - 35 * div35 * (div35 + 1) / 2
            + 105 * div105 * (div105 + 1) / 2;

        return sum;
    }
};

你可能感兴趣的:(#,Leetcode,算法)