【LeetCode】【Math】Self Dividing Numbers

【问题】

Self Dividing Numbers(自除数)是指该数能够被自己包含的每个数字整除。

例如,128%1 ==0,128%2 ==0,128%8 ==0,所以128是一个自除数。

注意,自除数是不能包含数字0。(0不能当除数)

所以,本题的要求是,给定一个上下边界,以列表的形式输出该区间包含所有自除数(包含边界)。

【例子】

Input: left = 1, right = 22

Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22]

【思路】

暴力破解:通过循环,对区间内的每个数字按照定义进行判断。

例如,对于128,我们要测试d!= 0 && 128%d == 0(对于d = 1、2、8)。为此,我们需要遍历数字的每个数字。

如何遍历数字的每个数字:

1、将数字转换为字符串,取出数字后转换为整数后,进行n%d == 0检验

2、将数字连续除以10,取最后一位,进行n%d == 0检验

【解法】

1、又长又啰嗦的本人的解法

class Solution:
    def selfDividingNumbers(self, left: int, right: int) -> List[int]:
        output = []
        for i in range(left,right+1):
            if "0" in str(i):
                continue 
            c = 0
            for n in range(0,len(str(i))):
                if i%int(str(i)[n]) == 0:
                    c += 1
                if c == len(str(i)):
                    output.append(i)
        return output

2、官方解法

class Solution(object):
    def selfDividingNumbers(self, left, right):
        def self_dividing(n):
            for d in str(n):
                if d == '0' or n % int(d) > 0:
                    return False
            return True
        """
        Alternate implementation of self_dividing:
        def self_dividing(n):
            x = n
            while x > 0:
                x, d = divmod(x, 10)
                if d == 0 or n % d > 0:
                    return False
            return True
        """
        ans = []
        for n in range(left, right + 1):
            if self_dividing(n):
                ans.append(n)
        return ans #Equals filter(self_dividing, range(left, right+1))

学习1:编写方程def self_dividing(n)

学习2:用False和True进行判定,我是用if c == len(str(i))进行判定,不如此法优雅,但解决思路是一样的

3、极简解法

基础版本

return [x for x in range(left, right+1) if all([int(i) != 0 and x % int(i)==0 for i in str(x)])]

优化版本

return [x for x in range(left, right+1) if all((i and (x % i==0) for i in map(int, str(x))))]

step by step

[
    x for x in range(left, right+1)  # iterate all numbers 遍历
    if all(  # whether all conditions in the list are true 条件判断
        [int(i) != 0 and x % int(i)==0  # translate each digit into int and check whether dividable 自除数判断
         for i in str(x)]  # translate int to an iterable string 遍历
    )
]

学习1:用int(i)代替int(i) == 0(因为在if 0: 判断为False,所以可以简写

学习2:all()函数

当判断condition1 and condition2 and condition3时,大部分compiler/intepreter是从左到右依次判断,如果condition1==False,就会直接返回False(这也被称作short-circuit evaluation.)。

在本题中,每个数只要有一个数字不满足就可以离开判断。下列代码是对每个数是否是自除数进行判读,

if all( [... for i in str(x)] )

会遍历每个数字,并将判断结果输出,例如x=128,输出[True, True, True],x=23,输出[False, False]

但如果第一个数字的结果是False就可以直接返回False,计算第二个数字就是浪费。所以可以将代码改为

if all( (... for i in str(x)) )

all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。

元素除了是 0、空、None、False 外都算 True。

函数等价于:

def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

Python 2.5 以上版本可用。

语法:all(iterable)  iterable -- 元组或列表。

返回值:如果iterable的所有元素不为0、''、False或者iterable为空,all(iterable)返回True,否则返回False;

注意:空元组、空列表返回值为True,这里要特别注意。

实例

>>> all(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
True
>>> all(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
False
>>> all([0, 1,2, 3])          # 列表list,存在一个为0的元素
False
   
>>> all(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
True
>>> all(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
False
>>> all((0, 1, 2, 3))          # 元组tuple,存在一个为0的元素
False
   
>>> all([])             # 空列表
True
>>> all(())             # 空元组
True

学习3:map()函数

因为把字符串转换为整数int会花费一些时间,因此我们可以先将字符串转换为int,而不是两次转换。

map(lambda x: int(x), str_to_convert)

map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

语法:map(function, iterable, ...)

  • function -- 函数
  • iterable -- 一个或多个序列

返回值:

Python 2.x 返回列表。

Python 3.x 返回迭代器。

实例

  

>>>def square(x) :            # 计算平方数
...     return x ** 2
... 
>>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
 
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]

参考:

https://www.runoob.com/python/python-func-map.html

https://www.runoob.com/python/python-func-all.html 

https://leetcode.com/problems/self-dividing-numbers/discuss/162578/One-line-Python-(Learn-some-Python-tricks-that-you-might-not-know)

猜你喜欢

转载自www.cnblogs.com/jialinliu/p/13176209.html