A self-dividing number is a number that is divisible by every digit it contains.
For example, 128 is a self-dividing number because 128 % 1 == 0, 128 % 2 == 0, and 128 % 8 == 0.
Also, a self-dividing number is not allowed to contain the digit zero.
Given a lower and upper number bound, output a list of every possible self dividing number, including the bounds if possible.
Example 1:
Input:
left = 1, right = 22
Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22]
原文:https://leetcode.com/problems/self-dividing-numbers/description/
依题所示,如果一个数字可以整除它所有位上的数字,那么就称为self-dividing number,我们需要设计一个算法来求出指定范围内满足的所有数字。
题目并不难,只需要不断使用当前数字除以不同位上的数字即可,但是需要注意的是self-dividing number中不含有0的,像10这种的肯定不行了,因为number中一旦包含0就无法让number本身除以0这一位了。
那么问题就转换成如果判断数字中是否含0,对于像10、20、100、300 这种的可以直接让其本身对10取模,观察余数是否为0即可,像101、203这种的,让其除以10,然后再取模运算判断。
那么很快便能写出如下解:
class Solution {
public:
vector<int> selfDividingNumbers(int left, int right) {
int temp = left;
vector<int> result;
for(int num=left;num<=right;num++) {// 在指定范围内循环
temp = num;
if(!(temp%10)) { // 判断是否属于10、20、300类型
continue;
}
while(temp && num%(temp%10) == 0) {// 如果当前位数满足条件就继续试探下一位
temp /= 10;
if(temp%10==0){ // 判断是否属于101、203这种的
break;
}
}
if(temp == 0) {
result.push_back(num);
}
}
return result;
}
};
这种是可以AC的,但是可以看到其中有不少冗余的代码,那么就需要优化一下减少冗余的代码。可以看出其中temp%10的取模运算重复了,那就可以使用一个mod变量直接保存。而100和101这种类型的可以统一放在一起判断。
代码如下:
class Solution {
public:
vector<int> selfDividingNumbers(int left, int right) {
int temp = left;
int mod;
vector<int> result;
for(int num=left;num<=right;num++) {// 在指定范围内循环
temp = num;
while(temp) {
mod = temp%10; // 求出此时的余数
if(mod==0 || num%mod!=0)// 如果此时余数等于0说明是10的倍数则退出,如果此时不满足条件也退出
break;
temp /= 10;
}
if(temp == 0) {
result.push_back(num);
}
}
return result;
}
};