SelfDividingNumbers [source code]
public class SelfDividingNumbers {
static
/******************************************************************************/
class Solution {
public List<Integer> selfDividingNumbers(int left, int right) {
List<Integer> res_ls = new ArrayList<> ();
assert left <= right && 1 <= left && right <= 10000;
for (int i = left; i <= right; i++) {
if (is_num_valid (i))
res_ls.add (i);
}
return res_ls;
}
public boolean is_num_valid (int num) {
int n = num;
while (num > 0) {
int digit = num % 10;
if (digit == 0 || (n % digit) != 0)
return false;
num /= 10;
}
return true;
}
}
/******************************************************************************/
public static void main(String[] args) {
SelfDividingNumbers.Solution tester = new SelfDividingNumbers.Solution();
}
}
这个是一个easy的题目, 所以笨办法其实是很简单的, 就是在这个range里面, 对每一个数字进行判断就行了; 但是这里要潜意识里意识到一个可能的提升空间, 就是这个题目展开的方式, 看起来好像他在鼓励你用check a number的方式来完成generate numbers的任务, 但是这样的做法真的是最好的吗? 当基本的mechanism跟实际上最后的题目目标有点区别的时候, 很多时候, 理解这个区别带来的方法的变化, 往往能够解决复杂度的瓶颈;
我现在又在尝试这种跳跃式的思考方式了; 思考了一会儿, 完全没有思路; 那么这个时候就fallback到下一个方法: 先尽可能细致的模拟出笨办法的做法, 然后在这个实现的过程中, 去寻找优化的可能性;
我们现在要做的是生成一个list, 那么如果单纯的穷举, 最后你就需要对每一个range内的数字都进行一个拆分digit然后divide的操作; 如果想要在这个aggregate的过程当中达到复杂度的优化, 那么一个可能的角度就是找到重复工作; 比如这里, 相同的digit可能会被range里面不同的数字进行多次的divide, 这个是否可以利用?
想了半天想不出来, 直接开始写笨办法;
笨办法倒是一次就通过了, 没有什么意外的地方; 速度是6ms (64%), 倒是不是显得很慢, 所以这题的最优解也没有多先进?
editorial里面只给了一个naive的解法:
class Solution {
public List<Integer> selfDividingNumbers(int left, int right) {
List<Integer> ans = new ArrayList();
for (int n = left; n <= right; ++n) {
if (selfDividing(n)) ans.add(n);
}
return ans;
}
public boolean selfDividing(int n) {
for (char c: String.valueOf(n).toCharArray()) {
if (c == '0' || (n % (c - '0') > 0))
return false;
}
return true;
}
// Alternate implementation of selfDividing:
// public boolean selfDividing(int n) {
// int x = n;
// while (x > 0) {
// int d = x % 10;
// x /= 10;
// if (d == 0 || (n % d) > 0) return false;
// }
// return true;
}
注意他这里检查divide的做法, 有一个更简单的方法就是不用数学来拆分digit, 直接用string来做, 这个想法也是没有问题的, 而且其实也很方便;
submission里面基本也就是这个解法了; 也有无聊蛋疼的直接用穷举的方法来做, 不过这个就很无聊了;
discussion也没有什么特别好的东西, 这个题目好像是上个月才出来的新题目, 所以现在基本就是没有什么好解法流出来;
Problem Description
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]
Note:
- The boundaries of each input argument are 1 <= left <= right <= 10000.
Difficulty:Easy
Total Accepted:13.7K
Total Submissions:20.2K
Contributor:jkl0619
Companies
epic systems
Related Topics
math
Similar Questions
Perfect Number
Hint 1
For each number in the range, check whether it is self dividing by converting that number to a character array (or string in Python), then checking that each digit is nonzero and divides the original number.