Easy
题目描述
给你一个正整数 n。判断 n 是否能被以下两个值的和整除:
n的数字和(各位数字的和)n的数字积(各位数字的积)
如果 n 能被这个和整除,返回 true;否则返回 false。
示例 1:
输入:n = 99
输出:true
解释:99 能被其数字和 (9 + 9 = 18) 与数字积 (9 * 9 = 81) 的和 (总计 99) 整除,所以输出为 true。
示例 2:
输入:n = 23
输出:false
解释:23 不能被其数字和 (2 + 3 = 5) 与数字积 (2 * 3 = 6) 的和 (总计 11) 整除,所以输出为 false。
提示:
1 <= n <= 10^6
解题思路
这道题的核心思路非常直接:
提取数字的各位数字:遍历数字
n的每一位,可以通过取模运算n % 10得到最后一位,然后整除n /= 10移除最后一位。计算数字和与数字积:在遍历过程中同时累加得到数字和,累乘得到数字积。
检查整除性:计算数字和与数字积的和,然后检查原数字
n是否能被这个和整除。
需要注意的边界情况:
- 当数字中包含 0 时,数字积会变成 0,此时数字和与数字积的和就等于数字和本身
- 由于
n是正整数且最大为10^6,不会出现除零的情况
算法步骤:
- 保存原始的
n值 - 逐位提取数字,同时计算数字和与数字积
- 返回
原始n % (数字和 + 数字积) == 0的结果
时间复杂度为 O(log n),因为需要遍历数字的每一位;空间复杂度为 O(1)。
代码实现
class Solution {
public:
bool checkDivisibility(int n) {
int original = n;
int digitSum = 0;
int digitProduct = 1;
while (n > 0) {
int digit = n % 10;
digitSum += digit;
digitProduct *= digit;
n /= 10;
}
return original % (digitSum + digitProduct) == 0;
}
};
class Solution:
def checkDivisibility(self, n: int) -> bool:
original = n
digit_sum = 0
digit_product = 1
while n > 0:
digit = n % 10
digit_sum += digit
digit_product *= digit
n //= 10
return original % (digit_sum + digit_product) == 0
public class Solution {
public bool CheckDivisibility(int n) {
int original = n;
int digitSum = 0;
int digitProduct = 1;
while (n > 0) {
int digit = n % 10;
digitSum += digit;
digitProduct *= digit;
n /= 10;
}
return original % (digitSum + digitProduct) == 0;
}
}
/**
* @param {number} n
* @return {boolean}
*/
var checkDivisibility = function(n) {
let digitSum = 0;
let digitProduct = 1;
let temp = n;
while (temp > 0) {
let digit = temp % 10;
digitSum += digit;
digitProduct *= digit;
temp = Math.floor(temp / 10);
}
return n % (digitSum + digitProduct) === 0;
};
复杂度分析
| 复杂度类型 | 分析 |
|---|---|
| 时间复杂度 | O(log n) - 需要遍历数字的每一位,位数为 log₁₀(n) |
| 空间复杂度 | O(1) - 只使用常数个变量存储中间结果 |