一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
题目描述
自除数 是指可以被它包含的每一位数整除的数。
- 例如,
128是一个 自除数 ,因为128 % 1 == 0,128 % 2 == 0,128 % 8 == 0。 自除数 不允许包含 0 。
给定两个整数 left 和 right ,返回一个列表,列表的元素是范围 [left, right] 内所有的 自除数 。
示例
输入: left = 1, right = 22
输出: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22]
输入: left = 47, right = 85
输出: [48,55,66,77]
提示
1 <= left <= right <= 10
逐位遍历
题目中要求该数值(num)可以被其每一位数整除,这里将步骤分解一下:
- 遍历数值的每一位元素
- 将
num对每一位元素取余,判断是否能整除 - 保存自除数
- 返回结果
class Solution {
public List<Integer> selfDividingNumbers(int left, int right) {
List<Integer> list = new ArrayList<>();
// 遍历区间
while(left <= right){
// 判断是否为自除数
if(dividingNumbers(left)){
// 保存自除数
list.add(left);
}
++left;
}
return list;
}
/**
* 除数判断
*
* @param num 数值
* @return 是否为除数
*/
public boolean dividingNumbers(int num){
// 数值转换成字符串
String str = String.valueOf(num);
// 遍历字符串
for(int i = 0; i < str.length(); ++i){
// 判断如果当前位置元素为 ‘0’,或者取余结果不为零,则不是自除数
if(str.charAt(i) == '0' || num % (str.charAt(i) - '0') != 0){
return false;
}
}
return true;
}
}
逐位遍历优化
上面的方法虽然能遍历每一位元素,不过每次都需要将数值转换成字符串,开销比较大,我们在这里可以采用取余来做一个优化:
- 复制一个数值,然后对
10取余,得到末位元素 - 判断是否为
0或者数值取余结果等不等于0 - 将复制的数值除以
10,以便于获取下一个元素 - 重复上面3个步骤,直至复制的数值为
0
class Solution {
public List<Integer> selfDividingNumbers(int left, int right) {
List<Integer> list = new ArrayList<>();
// 遍历区间
while(left <= right){
// 判断是否为自除数
if(dividingNumbers(left)){
// 保存自除数
list.add(left);
}
++left;
}
return list;
}
/**
* 除数判断
*
* @param num 数值
* @return 是否为除数
*/
public boolean dividingNumbers(int num){
// 复制
int tmp = num;
// 终止条件
while(tmp != 0){
// 判断末尾元素是否为0 或者数值对末尾元素能否整除
if(tmp % 10 == 0 || num % (tmp % 10) != 0){
return false;
}
// 去掉末尾元素
tmp /= 10;
}
return true;
}
}