• 旋转数字的解法


    旋转数字问题:
    
    我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后,我们仍可以得到一个有效的,且和 X 不同的数。
    要求每位数字都要被旋转。
    
    如果一个数的每位数字被旋转以后仍然还是一个数字, 则这个数是有效的。
    0, 1, 和 8 被旋转后仍然是它们自己;
    2 和 5 可以互相旋转成对方;
    6 和 9 同理,除了这些以外其他的数字旋转以后都不再是有效的数字。
    
    现在我们有一个正整数 N, 计算从 1 到 N 中有多少个数 X 是好数?
    
    示例:
    输入: 10
    输出: 4
    解释:
    在[1, 10]中有四个好数: 2, 5, 6, 9。
    注意 1 和 10 不是好数, 因为他们在旋转之后不变。
    
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/rotated-digits
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
    

    粗暴解法

    首先我拿到这个题目的思路就是分两个不同功能的方法。

    一个负责检查数字是否有效并且如果有效的话输出其反转后的数字,无效的话输出none,并且输出一个code,code的值表示了这个数的检查结果。

    检查功能代码如下:

    def check_active_turn_180(num):#只能处理单个数字
        i_turned=int()
        code=0  #0表示数字有效但反转后仍是其本身,1表示数字有效 3表示数字无效
        if num in active_nums:
            if num ==0 or num==1 or num==8:
                i_turned=num
                code = 0
            elif num ==2:
                i_turned=5
                code = 1
            elif num==5:
                i_turned=2
                code = 1
            elif num==6:
                i_turned=9
                code = 1
            elif num==9:
                i_turned=6
                code = 1
        else:
            code=3
            i_turned=None
        return (code,i_turned)
    

    这个功能的实现还是很粗暴的,简单地将所有有效数字储存在active_nums中,通过将输入的数字与active_nums中的数字进行检索和对比,由于有效数字样式较少,所以直接采用多个if分枝的方法实现识别特定数字并将其转换输出为i_turned。同时在输入非有效数字(如3,4,7)时输出None以及code=3。

    但是此功能只支持检查单个10以下数字,如137这样的数字就识别不了

    正因为识别不了二位数以上的数字,所以需要另外一个方法将数字转换成字符串,字符串再转换成列表,列表中的每个元素再转换成int然后使用check_active_turn_180方法检查每个数字,然后拿到的返回值,在str操作后加入一个新的列表,再将新的列表用join方法转换成一整个字符串。最后将新字符串进行int处理与原数字进行对比,如果与原数字相等,则丢弃,并break跳出循环。

    代码如下:

    def solution(N):
        i=1
        count=0
        while i <= N:
            if i <=10:
                check=check_active_turn_180(i)
                if check[0] ==1:
                    count+=1
            else:
                j=0 #控制循环次数 当大于拆分后的数字个数时停止循环
                lt_new=[] #用于暂存经过check后的单个数字,等待转为int
                lt=list(str(i))
                while j < len(lt):
                    num_in_lt=int(lt[j])
                    check=check_active_turn_180(num_in_lt)
                    if check[0] == 3:
                        i += 1
                        break
                    else:
                        lt_new.append(str(check[1]))
                    j += 1
                if  check[0] ==3:  #如果出现无效数字,跳出本次一层循环,进行下一次
                    continue
                else:#用于正常循环结束后
                    i_new=int(''.join(lt_new))
                if i_new != i:
                    count+=1
            i+=1
        return count
    

    虽然通过了leetcode的测试,但是成绩着实辣眼睛

    所以,在看了大神们的题解后,我看到了一个以我现在的python水平也能看得懂的答案。思路不同,但用的方法也很基础,没有涉及到我没学到的领域。

    其代码如下:

    def rotatedDigits(self, N):
        """
        :type N: int
        :rtype: int
        """
        changeDic = {
            '0' : '0',
            '1' : '1',
            '2' : '5',
            '5' : '2',
            '6' : '9',
            '8' : '8',
            '9' : '6'
        }
        result = 0
        for num in range(1, N + 1):
            num = str(num)
            value = ''.join([changeDic[x] for x in num if x in changeDic])
            if value != num and len(value) == len(num):
                result += 1
        return result
    

    分析了这种题解后,我将之对比我的解题方法,其不同主要体现在以下几个方面:

    • 采用了字典储存,将字典的key值对应数字值,而value值则对应反转后的数字,基本上一个字典就完成了我的整个检查功能
    • 格式设置较我的程序大幅完善,一次循环中仅用到一次str转换

    思考

    在下次设计程序中要事先考虑到最合适的数据类型的选择,避免通过多次类型转换将程序复杂化,到最后自己也看不懂

  • 相关阅读:
    第二次结对编程总结
    结对编程作业博客
    现状、经验和计划
    个人总结
    6月中旬开发心得
    读《软件开发沉思录》
    团队进度汇报
    个人课程总结
    Beta阶段总结
    冲刺第十天 1.11 FRI
  • 原文地址:https://www.cnblogs.com/Sheppard/p/11246135.html
Copyright © 2020-2023  润新知