一起刷力扣之【728. 自除数】

158 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

题目描述

自除数 是指可以被它包含的每一位数整除的数。

  • 例如,128 是一个 自除数 ,因为 128 % 1 == 0128 % 2 == 0128 % 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 <= 104^4

逐位遍历

题目中要求该数值(num)可以被其每一位数整除,这里将步骤分解一下:

  1. 遍历数值的每一位元素
  2. num对每一位元素取余,判断是否能整除
  3. 保存自除数
  4. 返回结果
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;
    }
}

逐位遍历优化

上面的方法虽然能遍历每一位元素,不过每次都需要将数值转换成字符串,开销比较大,我们在这里可以采用取余来做一个优化:

  1. 复制一个数值,然后对10取余,得到末位元素
  2. 判断是否为0或者数值取余结果等不等于0
  3. 将复制的数值除以10,以便于获取下一个元素
  4. 重复上面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;
    }
}