Python中的旋转数字

时间:2018-04-20 15:26:29

标签: python

我遇到了以下问题,我的解决方案通过了初始输入,但在以下测试用例中失败了。我不知道我错过了什么。

问题描述如下

X是一个很好的数字,如果将每个数字单独旋转180度后,我们得到一个与X不同的有效数字。每个数字必须旋转 - 我们不能选择不管它。

如果每个数字在旋转后仍为数字,则数字有效。 0,1和8旋转自己; 2和5相互旋转; 6和9相互旋转,其余数字不会旋转到任何其他数字并变为无效。

现在给出正数N,从1到N的X数是多少?

示例:

输入 10

输出 4

解释

[1,10]范围内有四个好的数字:2,5,6,9。 请注意,1和10不是好数字,因为它们在旋转后保持不变。

class Solution(object):
    def rotatedDigits(self, N):
        """
        :type N: int
        :rtype: int
        """
        rotatedDigits = [2,5,6,9]
        count = 0
        isValid = False
        for i in range(1,N+1):
                for b in str(i):
                    if int(b) in rotatedDigits:
                        isValid = True
                    else:
                        isValid = False
                        break
                if isValid:
                    count +=1
        return count

输入: 857

输出: 68

预期: 247

5 个答案:

答案 0 :(得分:3)

你的逻辑不完整。您正在检查是否存在旋转的数字,这是正确的。但问题陈述也说:

  

"其余数字不会旋转到任何其他数字而变得无效"

因此,如果数字包含数字3,4或7中的任何一个,则无效。

即使您要添加该支票,您的isValid标志也会出错。它应该在for循环内重置(不在其外部设置)。

这是您的功能版本:

def rotatedDigits(N):
    """
    :type N: int
    :rtype: int
    """
    rotatedDigits = {'2','5','6','9'}
    badNumbers = {'3','4','7'}
    count = 0
    for i in range(1,N+1):
        flag1 = False  # use this to check if the number contains a rotating digit
        flag2 = True  # use this to check if the number contains a bad digit
        for b in str(i):
            if b in rotatedDigits:
                flag1 = True
            elif b in badNumbers:
                flag2 = False
                break

        if flag1 and flag2:
            count +=1
    return count

print(rotatedDigits(857))
#247

我还制作了rotatedDigitsbadNumbers个字符串集,而不是整数列表。集查找比列表更快,这也避免了转换为字符串并返回到int。

更新:使用设置操作的更多pythonic版本:

def rotatedDigits(N):
    """
    :type N: int
    :rtype: int
    """
    rotatedDigits = {'2','5','6','9'}
    badNumbers = {'3','4','7'}
    count = 0
    for i in range(1,N+1):
        digits = set(str(i))
        count += 1 if (digits & rotatedDigits) and not(digits & badNumbers) else 0
    return count

这里我们在数字(digits)中创建一组字符,并在集合之间使用&运算符来获取交集。如果countdigits之间的交集不为空且rotatedDigitsdigits的交集为空,我们会增加badNumbers

可以使用summap和生成器表达式进一步压缩上述函数:

def rotatedDigits(N):
    """
    :type N: int
    :rtype: int
    """
    rotatedDigits = {'2','5','6','9'}
    badNumbers = {'3','4','7'}
    count = sum(1 if (x & rotatedDigits) and not (x & badNumbers) else 0 
                for x in map(lambda i: set(str(i)), range(1, N+1)))
    return count

答案 1 :(得分:1)

首先检查任何无效字符,我会采用不同的方法。然后验证它是否包含至少一个旋转字符。

rotating = {'2','5','6','9'}
invalid = {'3','4','7'}

def rotated(N):
    X=set(str(N))
    if any(digit in X for digit in invalid):
        return False
    if any(digit in X for digit in rotating):
        return True
    return False

def checkall(N):
    count=0
    for i in range(1,N+1):
        if rotated(i): 
            count += 1
    return count

print(checkall(857))

答案 2 :(得分:0)

使用此检查

if int(b) in rotatedDigits:
    isValid = True
else:
    isValid = False
    break

您错过了数字:0,1和8.在给定示例中,它们代表的数字保持不变但有效 您必须错过所有数字为3,4或7的数字。

答案 3 :(得分:0)

#使用字典:

def rotatedDigits(N: int):
    count=0
    d={0:0,1:1,2:5,3:-1,4:-1,5:2,6:9,7:-1,8:8,9:6}
    for i in range(1,N+1):
        l=list(str(i))
        res=[]
        for j in l:
            if d[int(j)]!=-1:
                res.append(str(d[int(j)]))
            else:break
        if len(res)==len(l) and int(''.join(res))!=i:
            count+=1
    return count

答案 4 :(得分:0)

首先,在 d_l 中创建一个 number[covered number to string] 列表,然后检查 bad_numbers 是否存在,然后检查 d_l 是否仅是有效数字的子集,然后如果任何数字通过所有条件,则意味着它是一个不错的数字。

def rotatedDigits(self, N: int) -> int:
        count = 0
        for d in range(1, N+1):
            d_l = [ch for ch in str(d)]
            if '3' in d_l or '4' in d_l or '7' in d_l:
                continue   
            if set(d_l).issubset({'0', '1', '8'}):
                continue    
            count += 1
        return count