Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
每日刷题第72天 2021.03.31
728. 自除数
- leetcode原题链接:leetcode-cn.com/problems/se…
- 难度:简单
- 方法:暴力模拟、打表
题目描述
- 自除数 是指可以被它包含的每一位数整除的数。
- 例如,128 是一个 自除数 ,因为 128 % 1 == 0,128 % 2 == 0,128 % 8 == 0。
- 自除数 不允许包含 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]
解题思路
- 根据题意:自除数不允许包含0(即:100、101这样的都不行)。给你一个区间范围,去查找这个区间中的自除数,并将其输出。
- 暴力模拟:观察数据范围:
10^4,计算最坏的情况,10^4 * 10^4 = 10^8也不会超出,因此可以使用暴力模拟。- 对于题目中所给的区间中的每一个值,都去判断下其是否为自除数。记区间内所有符合的自除数数组为
ans。若当前值是,则加入到数组中,若不是,则判断区间中的下一个值
- 对于题目中所给的区间中的每一个值,都去判断下其是否为自除数。记区间内所有符合的自除数数组为
新的解题思路
- 打表:提前将所有可能的样例以表格的形式打印出来(在自己本地的电脑上运行),然后再将代码放在
leetcode上,此时只需要把样例对应的答案输出即可。- 查找对应的样例的答案时间复杂度仅:o(1)
- 通常打表的使用场景:举例:假设一道题只有一个参数
n,这个参数n小于100,但是n = 100的时候,无论什么算法都会超时,这个时候就需要打表。- 此时在本地跑出来
n = 100时的答案,在写代码的时候只需要查找返回即可。
- 此时在本地跑出来
- 对于本题来说,你可以将区间
[1, 10000]之间的自除数全部打表出来,写代码的时候,直接查找区间内的值进行输出即可。 - 那么问题来了?如果查找到区间的开始位置呢?
- 可以使用二分查找,首先数组是有序的,二分查找的时间复杂度o(log(区间[1, 10000]之间的自除数个数)),那么整体的时间复杂度就是o(right - left + 1)
- 二分查找条件:查找第一个大于等于
left的值l:小于r:大于等于- 最终的结果返回
r即可
AC代码
var selfDividingNumbers = function(left, right) {
// 自除数不允许包含0,也就是说只要数字中有0均不行
// 自除数:1位数:自除本身
// [1,2,3,4,5,6,7,8,9]
// [11,12,14,15],[22,24],[33,36],[44,48],[55]
// 2位数:自除百位和各位
let ans = [];
function isOwnChu (num) {
//不包含0
let numPre = num;
while(num != 0) {
// 循环计算每一位
let wei = num % 10;
// console.log('wei:', wei)
if(numPre % wei != 0 || wei == 0){
return false;
}
num = parseInt(num / 10);
}
return true;
}
for (;left <= right; left++) {
// 判断其是否为自除数
// console.log('left', left)
if(isOwnChu(left)) ans.push(left)
}
return ans;
};
总结
- 一题多解,可以多多思考下