Easy
题目描述
自除数是指一个数能被它包含的每一位数字整除。
例如,128 是一个自除数,因为 128 % 1 == 0,128 % 2 == 0,128 % 8 == 0。
自除数不允许包含数字零。
给定两个整数 left 和 right,返回范围 [left, right](包括两端)内所有的自除数列表。
示例 1:
输入:left = 1, right = 22
输出:[1,2,3,4,5,6,7,8,9,11,12,15,22]
示例 2:
输入:left = 47, right = 85
输出:[48,55,66,77]
提示:
1 <= left <= right <= 10^4- 对于范围内的每个数字,通过将该数字转换为字符数组(或 Python 中的字符串)来检查它是否为自除数,然后检查每个数字是否非零并且能整除原数字。
解题思路
这道题需要判断一个数是否为自除数,然后找出给定范围内所有的自除数。
解题思路:
- 暴力遍历法:遍历 [left, right] 范围内的每个数,对每个数判断是否为自除数
- 自除数判断:对于每个数字,需要提取它的每一位数字,检查是否满足以下条件:
- 该位数字不为 0(题目要求)
- 原数字能被该位数字整除
具体实现步骤:
- 遍历范围内每个数字
- 对每个数字,通过取模和除法操作逐位提取数字
- 检查每一位是否为 0,如果是则跳过该数字
- 检查原数字是否能被该位数字整除,如果不能则跳过
- 如果所有位数字都满足条件,则将该数字加入结果
时间复杂度主要取决于数字的位数,由于题目限制最大为 10^4,所以每个数字最多 4 位,效率较高。
这是一个直接的模拟题,没有复杂的算法技巧,重点在于正确实现数字的位数提取和判断逻辑。
代码实现
class Solution {
public:
vector<int> selfDividingNumbers(int left, int right) {
vector<int> result;
for (int num = left; num <= right; num++) {
if (isSelfDividing(num)) {
result.push_back(num);
}
}
return result;
}
private:
bool isSelfDividing(int num) {
int original = num;
while (num > 0) {
int digit = num % 10;
if (digit == 0 || original % digit != 0) {
return false;
}
num /= 10;
}
return true;
}
};
class Solution:
def selfDividingNumbers(self, left: int, right: int) -> List[int]:
def is_self_dividing(num):
original = num
while num > 0:
digit = num % 10
if digit == 0 or original % digit != 0:
return False
num //= 10
return True
result = []
for num in range(left, right + 1):
if is_self_dividing(num):
result.append(num)
return result
public class Solution {
public IList<int> SelfDividingNumbers(int left, int right) {
var result = new List<int>();
for (int num = left; num <= right; num++) {
if (IsSelfDividing(num)) {
result.Add(num);
}
}
return result;
}
private bool IsSelfDividing(int num) {
int original = num;
while (num > 0) {
int digit = num % 10;
if (digit == 0 || original % digit != 0) {
return false;
}
num /= 10;
}
return true;
}
}
/**
* @param {number} left
* @param {number} right
* @return {number[]}
*/
var selfDividingNumbers = function(left, right) {
const result = [];
for (let num = left; num <= right; num++) {
if (isSelfDividing(num)) {
result.push(num);
}
}
return result;
};
function isSelfDividing(num) {
const str = num.toString();
for (let i = 0; i < str.length; i++) {
const digit = parseInt(str[i]);
if (digit === 0 || num % digit !== 0) {
return false;
}
}
return true;
}
复杂度分析
| 复杂度类型 | 分析 |
|---|---|
| 时间复杂度 | O((right - left + 1) × log₁₀(max(right))) |
| 空间复杂度 | O(1)(不考虑输出数组的空间) |
说明:
- 时间复杂度:需要遍历 [left, right] 范围内的每个数字,对每个数字需要检查其每一位,数字的位数为 log₁₀(数字)
- 空间复杂度:只使用了常数级别的额外空间来存储临时变量