旋转数字问题:
我们称一个数 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转换
思考
在下次设计程序中要事先考虑到最合适的数据类型的选择,避免通过多次类型转换将程序复杂化,到最后自己也看不懂