Leetcode1 有趣的数字(基础篇-上)

305 阅读7分钟

1.阿姆斯特朗数

1.armStrong.py:

#!/usr/bin/python
# Env: python3
# Rewrite by afei_0and1

'''
1、假设存在一个k位数N,其每一位上的数字的k次幂的总和也是N,那么这个数就是阿姆斯特朗数。
现在给你一个正整数N,让你来判定这个数是否是阿姆斯特朗数,如果是,返回True,如果不是,返回False。
EG:153是一个3位数,且:153=1^3+5^3+3^3 

    阿姆斯特朗数其实是一种自幂数,三位的阿姆斯特朗数又被称为水仙花数。
水仙花数的名字来自于一个凄美的神话故事,美少年纳西索斯苦苦追求自己的倒影最终化作一朵晶莹剔透的水仙花。
之后,纳西索斯的名字(NARCISSUS)就成了“自我欣赏”的代名词,用水仙花数来称呼3位的自幂数,或许要有些描述“自赏”的味道。

有趣的自幂数:
    一位的自幂数又称独身数;
    三位的自暴数又称水仙花数;
    四位的自幂数又称四叶玫瑰数;
    五位的自幂数又称五角星数;
    六位的自幂数又称六合数;
    七位的自幂数又称北斗七星数;
    八位的自幂数又称八仙数;
    九位的自幂数又称九九重阳数;
    十位的自幂数又称十全十美数。

解题思路:
    (1)首先将一个数中的每一位数字提取出来;
    (2)将提取出来的每一位数字与当前数本身的位数进行指数运算并且累加;
    (3)最后比较累加的结果与数字本身是否相同。
'''

def armStrong(N):
    tmp = N
    list = []
    while tmp / 10.0 > 0:
        #取个位数字
        s = tmp % 10
        list.append(s)
        tmp = tmp // 10
    sum = 0
    for item in list:
        sum += item**len(list)
        #print(item**len(list))
    if sum == N:
        return True
    else:
        return False

res = armStrong(153)
print(res)

'''
Output result:
    True
'''

#程序优化
def armStrong2(N):
    strN = str(N)
    list = []
    for item in strN:
        list.append(item)
    sum = 0
    for item in list:
        sum += int(item) ** len(list)
    return sum == N

res = armStrong2(100)
print(res)

'''
Output result:
    False
'''

#程序优化2
def armStrong3(N):
    l = list(str(N))
    sum = 0
    for item in l:
        sum = int(item) ** len(l)
    return sum == N

res = armStrong2(153)
print(res)

'''
Output result:
    True
'''

2.自除数

2.self-Divisor.py:

#!/usr/bin/python
# Env: python3
# Rewrite by afei_0and1

'''
2、自除数是指可以被它包含的每一位数除尽的数,也可以理解为,自除数对组成其本身的
每一位数字进行取余操作,结果都为0,注意:自除数不允许包含0。如:128是一个自除数,
因为:128 % 1 == 0,128 % 2 == 0,128 % 8 == 0。

    现在,给定上边界和下边界的数字,输出一个列表,列表的元素是边界(含边界)内所有
的自除数。请尝试解决。
'''

def selfDivisor(left, right):
    l = []
    for num in range(left, right+1):
        numStr = str(num)
        numList = list(numStr)
        res = True
        for item in numList:
            itemNum = int(item)
            #剔除自除数为0的情况
            if itemNum == 0:
                res = False
                break
            #剔除不能自身除尽的情况
            if num % itemNum != 0:
                res = False
        #将自除数添加到列表中
        if res:
            l.append(num)
    return l
    
print(selfDivisor(100, 200))

'''
Output result:
    [111, 112, 115, 122, 124, 126, 128, 132, 135, 144, 155, 162, 168, 175, 184]
'''

#程序优化1
def selfDivisor2(left, right):
    l = [num for num in range(left, right+1) if([item for item in list(str(num)) if (int(item) != 0 and num % int(item) == 0)] == list(str(num)))]
    return l
        
print(selfDivisor2(128, 201))

'''
Output result:
    [128, 132, 135, 144, 155, 162, 168, 175, 184]
'''

3.完全平方数

3.entire-SquareNumber.py:

#!/usr/bin/python
# Env: python3
# Rewrite by afei_0and1

'''
3、完全平方数有这样的特性:如果一个正整数A是某一个整数B的平方,那么这个正整数A叫做完全平方数,零也可称为完全平方数。
    那么:给定正整数N,找到若干个完全平方数使得它们的和等于N,你需要确定组成和的完全平方数的最少的个数。
    例如:对于正整数13,其可以拆解为13=4+9,则最少个数为2;对于正整数12,其可以拆解为12=4+4+4,则最少个数为3.

解题需用到:四平方数和定理
    四平方数和定理又称拉格朗日四平方数和定理,由拉格朗日最终解决。
    四平方数和定理可以证明:任何正整数均可表示为四个整数的平方和(其中允许有整数为0)。
    根据四平方数和定理:
        13 = 4 + 9 + 0 + 0
        12 = 4 + 4 + 4 + 0
    从该定理可知:组成这个正整数N的完全平方数的个数最多为4个。
    四平方数和定理推论:
        如果一个数N只能使用4个非零的完全平方数的和表示,则这个数N一定满足:4^A(8B+7)

解题算法思路:
(1)先假设组成这个数N的完全平方数的个数最少为4,则数N必定满足:N=4^A(8B+7),
先对这个等式进行判断,如果通过,则最终答案为4,否则继续算法;
(2)假设组成这个数N的完全平方数的个数最少为1,则数N可以表示为某个正整数的平方,
进行遍历,如果找不到继续算法;
(3)假设组成这个数N的完全平方数的个数最少为2,使用循环嵌套进行遍历,找不到继续算法;
(4)算法执行到此,则最终答案为3。
'''

def entireSquareNumber(N):
    num = N
    #判断是否是4的倍数
    while num % 4 == 0:
    #判断是否满足:4^A(8B+7)
        num = num / 4
    if num % 8 == 7:
        return 4
    for i in range(1, N+1):
        if i * i == N:
            return 1
    for i in range(1, N+1):
        for j in range(1, N+1):
            if i * i + j * j == N:
                return 2
    return 3
print(entireSquareNumber(100))

'''
Output result:
    1
'''

'''
    如果给定的N数值很大,由于经过多次循环和幂运算,导致程序很慢。
'''
#程序优化

import math

def entireSquareNumber2(N):
    num = N
    while num % 4 == 0:
        num = num / 4
    if num % 8 == 7:
        return 4
    #导入math库,math.sqrt()开方运算,math.pow()幂运算
    if math.pow(int(math.sqrt(N)), 2) == N:
        return 1
    max = int(math.sqrt(N)) + 1
    for i in range(1, max):
        tmp = N - i * i
        if math.pow(int(math.sqrt(tmp)), 2) == tmp:
            return 2
    return 3

print(entireSquareNumber2(7000))

'''
Output result:
    3
'''

4.强整数

4.strongInteger.py:

#!/usr/bin/python
# Env: python3
# Rewrite by afei_0and1

'''
    强整数有这样的定义,给定两个正整数X和Y,如果某一整数等于X^I+Y^J,
其中整数I>=0且J>=0,那么我们认为该整数是一个强整数。

    现在,输入X和Y,给定一个上边界N,尝试编程找出小于等于N的所有强整数,通过列表的方式返回。
'''

import math

def strongInteher(x, y, bounds):
    l = []
    for i in range(0, bounds + 1):
        # x^i大于bounds的情况
        if math.pow(x, i) > bounds:
            break
        for j in range(0, bounds + 1):
            res = math.pow(x, i) + math.pow(y, j)
            if res <= bounds:
                if int(res) not in l:
                    l.append(int(res))
                else:
                    if x == 1:
                        return l
                    else:
                        break
    return l
print(strongInteher(2, 3, 20))

'''
Output result:
    [2, 4, 10, 3, 5, 11, 9, 17, 19]
'''

'''
程序优化:
    (1)使用元组;
    (2)使用栈结构
'''

def strongInteher2(x, y, bounds):
    l = []
    stack = [(0, 0)]
    while len(stack) > 0:
        #获取列表中的一个元素,默认是最后一个元素
        tmp = stack.pop()
        res = math.pow(x, tmp[0]) + math.pow(y, tmp[1])
        if res <= bounds:
            if int(res) not in l:
                l.append(int(res))
            # res>bounds的情况
            if x != 1:
                stack.append((tmp[0] + 1, tmp[1]))
            if y != 0:
                stack.append((tmp[0], tmp[1] + 1))
    return l
print(strongInteher2(2, 3, 22))

'''
Output result:
    [2, 4, 10, 11, 13, 17, 5, 7, 19, 3, 9]
'''

5.回文数

5.palindromicNumber.py:

#!/usr/bin/python
# Env: python3
# Rewrite by afei_0and1

'''
5、"回文"是指一个句子正读和反读都能读通,在数学中也有这样一类数字有这样的特征,
被称为“回文数”。回文数是指正序(从左到右)和倒序(从右到左)读都是一样的整数。

    现要求输入一个整数N,判断其是否是回文数。
    
解题思路:
    将输入的数转为列表,通过列表的逆序判断是否是回文数。
'''

def palindromicNumber(N):
    list1 = list(str(N))
    list2 = list(str(N))
    list2.reverse()
    return list1 == list2

print(palindromicNumber(121))

'''
Output result:
    True
'''

'''
程序优化:
    使用切片减少代码量
'''

def palindromicNumber2(N):
    # -1代表从右往左,第二位代表步长
    return str(N) == str(N)[::-1]
    
print(palindromicNumber2(112111))

'''
Output result:
    False
'''

更多文章:afei00123.blog.csdn.net/