当前位置: 首页 > news >正文

同题异构解决leetcode第3646题下一个特殊回文数

3646.下一个特殊回文数

难度:困难

问题描述:

给你一个整数n。

如果一个数满足以下条件,那么它被称为特殊数:

它是一个回文数。数字中每个数字k出现恰好k次。返回严格大于n的最小特殊数。

如果一个整数正向读和反向读都相同,则它是回文数。例如,121是回文数,而123不是。

示例1:

输入:n=2

输出:22

解释:

22是大于2的最小特殊数,因为它是一个回文数,并且数字2恰好出现了2次。

示例2:

输入:n=33

输出:212

解释:

212是大于33的最小特殊数,因为它是一个回文数,并且数字1和2恰好分别出现了1次和2次。

提示:

0<=n<=10**15

问题分析:

这个题目很容易让人想到用枚举算法,从给定的数向后枚举,然后检验这个数是否是一个回文数,且这个回文数中的每个数字出现次数恰好等于这个数字,直到碰到第一个符合条件的数为止,这个数即是所要求的回文数。

为此设计一个检验函数check_is_result(n),该函数用于判断一个整数是否为一个回文数,且这个回文数中的每个数字出现次数恰好等于这个数字,如果满足这些条件则返回True,否则返回False。

剩下就是利用枚举算法构造循环来解决这个问题了。

程序如下:

#检查一个整数是否是满足题目中条件的回文数:即它是一个回文数,且数字中每个数字k出现恰好k次。
def check_is_result(n):n=str(n)n_bak=n[::]if n==n[::-1]:n=list(n)t=set(n)for i in t:c=n_bak.count(i)if int(i)!=c:return Falseelse:return Trueelse:return False#主程序
n=int(input('pls input n='))
i=1
while True:n = n + 1if check_is_result(n):print(n)break

运行实例一

pls input n=1

22

运行实例二

pls input n=22

212

运行实例三

pls input n=1000000000

2888888882

通过枚举算法确实思路简单,但上面的运行实例三,运行时间很长,大约过了20分钟左右才出来答案,循环从1000000001枚举到2888888882,是一个天文数字的循环次数,且每一个数字都要进行复杂的检验,可见效率低下。

为此考虑,根据输入的数字n,直接构造大于n的最小特殊数。

构造特殊数,就要找到构造特殊数的规律。

通过枚举的方法,找到一些特殊数如下:

22  (两位)

212   333 (三位)

4444  (四位)

23332  32323  44144  55555 (五位)  

244442  424424  442244  666666  (六位)

2441442  2555552  3443443  4241424  4343434  4421244  4433344  5255525  5525255  6661666  7777777 (七位)

可以看出,特殊数组成的序列,是一个固定序列,与输入的整数n没有太大的关系,只和整数n的数字位数有关,可以想到大于整数n的最小特殊数可能数字位数和n相等,或者比n的数字位数多一位,比如参照上面的特殊数序列,如果输入的n在2到21之间,输出结果都应该是22,如果输入的n在22到211之间,输出结果都应该是212。

再观察上面的特殊数序列,如果特殊数是偶数位,则全部由偶数组成这个特殊数的每一位数字,如果特殊数是奇数位,则构成特殊数的数字只能有一位奇数,其它都偶数,其中原因不难想见。

因此,可以这样来解决问题:

根据输入整数n的数字位数,把与n位数相同的特殊数以及比整数n位数多一位的特殊数也找出来,并构成一个特殊数的序列,并把整数n也加入这个序列,然后按大小排序,则比整数n大的最小特殊数不是就很容易找出了吗?

程序如下:

def one_into_array(one,my_array):a=[]n=len(my_array)for i in range(n+1):l=my_array[0:i]r=my_array[i:]b=l+[one]+ra.append(b)return adef get_all_array(my_list):n=len(my_list)if n==1:return[my_list]elif n==2:t=[my_list,my_list[::-1]]t.sort()return telse:l=my_list[0]r=my_list[1:]b=get_all_array(r)c=[]for i in b:c.extend(one_into_array(l,i))c.sort()return cdef get_o_num_list(n):a=[[2],[4],[6],[2,4],[8],[2,6],[2,8],[4,6],[4,8],[2,4,6],[6,8],[2,4,8],[2,6,8],[4,6,8],[2,4,6,8]]o_array=[]for i in a:if sum(i)==n:o_array.append(i)return o_arraydef get_j_num_list(n):a=[1,3,5,7,9]b=[]for i in a:old_list = get_o_num_list(n - i)for j in old_list:j.append(i)b.append(j)if n<10:b.append([n])return b#生成一半的回文
def get_o_palindrome(n):b_list=get_o_num_list(n)a=[]for i in b_list:x=[]for j in i:t=[j]*(j//2)x.extend(t)a.append(x)b=[]for i in a:t=get_all_array(i)b.extend(t)a=[]for i in b:t=list(map(str,i))a.append(t)b=[]for i in a:t=''.join(i)b.append(t)b=list(set(b))a=[]for i in b:t=i+i[::-1]a.append(t)return adef get_j_palindrome(n):b_list = get_j_num_list(n)# print(b_list)a = []for i in b_list:x = []for j in i:if j%2==0:t = [j] * (j // 2)x.extend(t)else:if j!=1:t=[j]*((j-1)//2)x.extend((t))else:t=[j]x.extend(t)a.append(x)b = []for i in a:if 1 in i and len(i)>1:i.remove(1)t = get_all_array(i)t=list(k+[1] for k in t)b.extend(t)else:t=get_all_array(i)b.extend(t)c=[]for i in b:t=list(map(str,i))c.append(t)a = []for i in c:t = ''.join(i)a.append(t)a=list(set(a))#['32', '441', '23', '55']b=[]for i in a:t=''if '1' in i:c=i[:len(i)-1]t=i+c[::-1]b.append(t)else:for j in ['3','5','7','9']:if j in i:c=i[::-1]t=i+j+cb.append(t)breakreturn b#主程序
n=int(input('pls input n='))
n=str(n)
n_len=len(n)
a=[]
if n_len==1:a=['1','22']
else:if n_len % 2 == 0:b = get_o_palindrome(n_len)a.extend(b)c = get_j_palindrome(n_len + 1)a.extend(c)else:c = get_j_palindrome(n_len)a.extend(c)b = get_o_palindrome(n_len + 1)a.extend(b)
a.append(n)
a=list(map(int,a))
a.sort()
i=a.index(int(n))
result=a[i+1] if a[i+1]!=a[i] else a[i+2]
print(result)

运行实例一

pls input n=0

运行实例二

pls input n=10000
23332

运行实例三

pls input n=123456789

234434432

运行实例四

pls input n=12345678998765432

23448888388884432

通过这种方法生成速度明显快了很多。

枚举方法的运行实例三,要20分钟左右才能得到结果,但用第二种直接构造的方法,基本上一秒钟就完成。

同题异构,展现不同的算法思维,让枯燥的数字因为你的思想而迸发出耀眼的光芒。

http://www.xdnf.cn/news/1342261.html

相关文章:

  • Effective C++ 条款55:熟悉Boost库
  • 2025-08-21 Python进阶2——数据结构
  • imx6ull-驱动开发篇33——platform 平台驱动模型
  • C++ this 指针
  • 分治思想在系统分流削峰中的实践与Golang前沿实现
  • Python读取和设置PNG图片的像素值
  • MFC随笔—不使用对话框资源模板创建对话框
  • Effective C++ 条款54:熟悉标准库
  • 【lucene】lucene常用查询一览
  • python 项目编号 2025821 有关于中英文数据的收集、处理
  • 数据结构之排序大全(3)
  • Python数据可视化利器:Matplotlib从入门到实战全解析
  • C ++代码学习笔记(一)
  • TDengine IDMP 运维指南(常见问题)
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(18):文法+单词第6回1
  • 虚幻基础:曲线
  • 基于STM32单片机的二维码识别物联网OneNet云仓库系统
  • 图--常见面试问题
  • 从源码中学习Java面向对象的多态
  • 多级缓存一致性矩阵:ABP vNext 下的旁路 / 写穿 / 写回组合实战
  • MiniGPT-4
  • FPGA 在情绪识别领域的护理应用(三)
  • 机器学习1
  • 结合 Flutter 和 Rust 的跨平台开发方案
  • Vibe Coding v.s Prompt Engineering
  • 数据库面试常见问题
  • gsplat在windows本地部署
  • Dockerfile
  • Claude Code 已支持【团队版】和【企业版】订阅
  • Webpack的使用