题目

类型:数学
image.png

解题思路

在打表预处理了所有范围内的自除数的基础上,可以干脆将索引也预处理出来,从而避免二分操作
其中 hash[x] 的含义为值不超过 x 的最大自除数在 list 中的下标。

代码

  1. class Solution {
  2. //存储自除数
  3. static List<Integer> list = new ArrayList<>();
  4. //存储自除数在list中的位置
  5. static int[] hash = new int[10010];
  6. //预处理10000个数字中的自除数
  7. static {
  8. for (int i = 1; i <= 10000; i++) {
  9. int cur = i;
  10. boolean ok = true;
  11. while (cur != 0 && ok) {
  12. int u = cur % 10;
  13. if (u == 0 || i % u != 0) {
  14. ok = false;
  15. }
  16. cur /= 10;
  17. }
  18. if (ok) {
  19. list.add(i);
  20. }
  21. hash[i] = list.size() - 1;
  22. }
  23. }
  24. public List<Integer> selfDividingNumbers(int left, int right) {
  25. List<Integer> ans = new ArrayList<>();
  26. //如果left属于自除数,把结果赋值给idx,否则进入下一位
  27. int idx = list.get(hash[left]) == left ? hash[left] : hash[left] + 1;
  28. //如果idx在list范围内,且在right范围内,加入结果的list中
  29. while (idx < list.size() && list.get(idx) <= right) {
  30. ans.add(list.get(idx++));
  31. }
  32. return ans;
  33. }
  34. }