当前位置: 首页 > 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.dtcms.com/a/343390.html

相关文章:

  • Linux网络socket套接字(上)
  • linux 之virtio 的驱动框架
  • Motocycle 智能仪表盘
  • 白光干涉测量系统的复合相移三维重建和多视场形貌拼接的复现
  • 【自然语言处理与大模型】微调与RAG的区别
  • JavaScript基础语法five
  • 【Protues仿真】基于AT89C52单片机的数码管驱动事例
  • 力扣905:按奇偶排序数组
  • 2025-08-21 Python进阶4——错误和异常
  • 开发者中使用——控制台打印数据
  • 爬虫基础学习-基本原理和GET请求
  • JavaScript 基本语法
  • 智慧城市SaaS平台/市政设施运行监测系统之空气质量监测系统、VOC气体监测系统、污水水质监测系统及环卫车辆定位调度系统架构内容
  • 学习嵌入式之驱动
  • 3.2.6 混凝土基础施工
  • Chrome 内置扩展 vs WebUI:浏览器内核开发中的选择与实践
  • C++入门自学Day16-- STL容器类型总结
  • Git标准化开发流程
  • iOS 应用上架多环境实战,Windows、Linux 与 Mac 的不同路径
  • 详解开源关键信息提取方案PP-ChatOCRv4的设计与实现
  • 哈尔滨云前沿服务器租用类型
  • IoTDB如何解决海量数据存储难题?
  • 多模态大模型研究每日简报【2025-08-21】
  • Python学习-- 数据库和MySQL入门
  • 在线课程|基于SprinBoot+vue的在线课程管理系统(源码+数据库+文档)
  • 华为仓颉语言的函数初步
  • rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(三) 文本标签、按钮、文本框基本使用
  • Rust 入门 模块 (二十二)
  • 意象驱动下的感知与认知信息结构:上古汉语同源词研究视角——基于黄易青《上古汉语同源词意义系统研究》的理论框架
  • Eject配置