场景:
我同门最近面试字节三面,面试官给的算法题是,下一个回文数,就是找出当前给的数字的下一个回文数,前提是要比原始数字大。OK,他给我讲了思路,然后,我也是兜兜转转才写出来,,我太菜了,唉,而且,我没想到的是,这个题虽然是困难题,但是并没有判断一个数字是不是回文数那一步。
问题
其实,很多时候,写不出程序,根本原因在于思路不清晰,脑子里没有清晰的算法流程,所以,写得一团糟。
那么,回到这个题的思路。
首先,这个题目的要求是求比原始数字大的回文数,那么,肯定首先要想到用字符串。进行切片和重组操作,这样是最快的。那么,应该怎么切呢?记住我们的核心思想是进行翻转和重组!
分两种情况,首先是判断当前数字的位数位奇数还是偶数。
如果是奇数,那么,只能对前半部分进行处理翻转。例如,我们当前输入是13342,长度位5个数字的输入。那么,我们会对133这三位数进行翻转粘贴。具体操作为:将133的前两位进行翻转,得到31,再把这两位粘贴到133的后面,得到13331。很明显,这是一个回文数。但是,很明显不符合要求,因为13331小于13342。因此,我们要将原数前半部分133进行加1,得到134,再重复刚刚的操作。将134的前两位进行翻转,得到31,再把这两位粘贴到134的后面,得到13431,符合要求!!
如果是偶数,那么操作简单很多,也是一样的。只对前半部分进行处理翻转,例如,我们当前输入是2233,那么,我们会将22进行翻转。获得22,再粘贴上2233的头部22得到2222。2222小于2233,不符合题意。那么,进一步,我们将原数前半部分22加一,得到23,在进行翻转,得到32,再粘贴再23的后面,获得2332。2332>2233,符合要求!!
def get_next_reverse_number(n, flag, step):
'''
:param n: 当前输入的数字大小
:param flag: 用于判断是奇数还是偶数, True为奇数
:param step: 判断是否是第一次翻转,第一次step==0,后续就不等于0了
:return: 翻转后的数字
'''
s = str(n)
mid_lenth = len(s) // 2
if flag: # 奇数处理方式
if step == 0: # 奇数第一次翻转
s = s[0:mid_lenth + 1]
new_numb = int(s + ''.join([_ for _ in s[0:-1]][::-1]))
return new_numb
else:
s = s[0:mid_lenth + 1]
s = str(int(s) + 1) # 第N (N>1)次翻转 记得加一
new_numb = int(s + ''.join([_ for _ in s[0:-1]][::-1]))
return new_numb
else: # 偶数处理方式
if step == 0: # 偶数第一次翻转
s = s[0:mid_lenth]
new_numb = int(s + ''.join([_ for _ in s][::-1]))
return new_numb
else:
s = s[0:mid_lenth]
s = str(int(s) + 1) # 第N (N>1)次翻转,记得加一
new_numb = int(s + ''.join([_ for _ in s][::-1]))
return new_numb
def next_huiwen_Number(n):
# 个位数的情况
if n < 10:
return n + 1
# 9999或者999的情况,因为要进位
if len(str(n + 1)) > len(str(n)):
return n + 2
step = 0 # 用来判断是第一次还是第二次操作,因为第一次只需要翻转就行,不需要前半截加一!
if len(str(n)) % 2 == 1: # 判断奇数还是偶数
new_number = get_next_reverse_number(n, True, step)
while new_number <= n:
step += 1
new_number = get_next_reverse_number(n, True, step)
else:
new_number = get_next_reverse_number(n, False, step)
while new_number <= n:
step += 1
new_number = get_next_reverse_number(n, False, step)
return new_number
if __name__ == '__main__':
print(next_huiwen_Number(13342))