
2026-06-19:阶数数字排列。用go说话,给定一个整数 n,判断能否把 n 的诸君数字再行排列(允许使用本来的规则,也允许换成淘气规则),得到某个有用整数,使得它满足底下的性质:
• 对这个新整数的每一位数字 d,经营 d!(d 的阶乘)。
• 把整个位数字的阶乘完了相加。
• 要是这个“位数字阶乘之和”正巧就是该整数自己,则这个整数称为“阶数数字”。
要求磋商整个排列的可能性,但排列必须是有用的:弗成以 0 起原(不然该排列视为无效)。
要是存在至少一种有用排列能酿成阶数数字,复返 true;不然复返 false。
1
输入: n = 145。
输出: true。
诠释:
数字 145 自己是一个阶数数字,因为 1! + 4! + 5! = 1 + 24 + 120 = 145。因此,谜底为 true。
题目来独力扣3848。
一、举座解题中枢念念路先梳理
题目要求:给定数字n,把它所稀有字作念不含前导0的排列,唯有淘气一个排列x满足「x每一位阶乘相加 = x自己」,就复返true。
中枢数学要道点:
1. 无论数字奈何排列,诸君数字聚会不变 → 诸君数字阶乘的总和S是固定值,和排列规则无关;
2. 假定某排列x是正当阶数数字,则势必满足 x = S;
3. 扩充:独一有可能顺应要求的候选数字,只然而诸君阶乘总和S。只需要考据两件事:
① S的数字多重聚会 和 原数字n的数字多重聚会都备疏通(即互为排列);
② S弗成以0起原(S自身当然不会前导0,因为是时常整数)。
原代码都备基于这个扩充达成,不需要成列整个排列,极大裁汰复杂度。
二、分才智审视拆解实施经过(以输入n=145例如)
才智1:全局预解决0~9的阶乘数组(init函数瞻望算,规范启动只实施一次)
1. 界说长度为10的数组fac,运转fac[0]=1(数学公法0! = 1);
2. 轮回i从1到9,挨次经营每个数字的阶乘:
• fac[1] = fac[0] * 1 = 1! = 1
• fac[2] = fac[1] * 2 = 2! = 2
• fac[3] = 6、fac[4]=24、fac[5]=120……直到fac[9]=362880;
3. 作用:后续取数字d时,平直查表拿d!,毋庸重叠经营阶乘。
才智2:参加判断函数 isDigitorialPermutation(n int),分三大阶段
阶段A:遍历原数字n的每一位,完成两件事:累加阶乘和、统计数字出现次数
输入示例n=145,轮回要求 n>0,每次对10取模取个位,再除以10截断:
1. 运改动两个变量:
• sumFac:存储整个位阶乘累加和,运转0;
• cnt[10]数组:长度10,记载0-9每个数字在原数里出现的次数,运转全0;
2. 第一轮 n=145:
d = 145 % 10 = 5;sumFac += fac[5]=120 → sumFac=120;cnt[5] +=1 → cnt[5]=1;n更新为14;
3. 第二轮 n=14:
d=14=4;sumFac += fac[4]=24 → sumFac=144;cnt[4] +=1 → cnt[4]=1;n更新为1;
4. 第三轮 n=1:
d=1=1;sumFac += fac[1]=1 → sumFac=145;cnt[1] +=1 → cnt[1]=1;n更新为0;
5. 轮回断绝;
此时得到:
• sumFac = 145(所稀有字阶乘总和);
• cnt数组记载原数字:1出现1次、4出现1次、5出现1次,其尾数字0次。
阶段B:遍历候选数字sumFac的每一位,对消cnt数组计数
中枢逻辑:要是sumFac和原数n是数字重排列,那么两者每个数字出现次数都备相配,遍历sumFac每一位,对应cnt数字计数减1,开运(中国)最终整个cnt必须归零。
轮回要求 sumFac>0,每次取个位、除以10:
1. 第一轮 sumFac=145:个位5 → cnt[5] -=1 → cnt[5]=0;sumFac=14;
2. 第二轮 sumFac=14:个位4 → cnt[4] -=1 → cnt[4]=0;sumFac=1;
3. 第三轮 sumFac=1:个位1 → cnt[1] -=1 → cnt[1]=0;sumFac=0;
4. 轮回断绝;
阶段C:校验cnt数组是否沿途为0,复返布尔完了
1. 对比cnt数组和全零数组[10]int{0,0,...0};
2. 示例中整个位置都是0,等式树立,复返true;
补充反例:若原数是146,sumFac=1!+4!+6! = 1+24+720=745;遍历745会给cnt[7]、cnt[4]、cnt[5]减1,原cnt是1、4、6各一次,最终数组存在非0数字,复返false。
才智3:main函数实施经过
1. 给定输入n=145;
2. 调用判断函数,接管复返布尔值;
3. 打印输出完了true。
三、补充界限逻辑证据(题目贬抑n∈[1,1e9])
1. 前导0校验:本算法自然遁藏无效排列问题。
若存在正当无0起原排列x满足要求,则x=sumFac,sumFac是粗鄙正整数,自己不可能以0起原;
若sumFac首位为0,只然而sumFac=0,但n≥1,原数字至少有1个非0数字,sumFac不可能为0,无需额外判断前导0;
2. 无需成列全排列:通例暴力成列数字排列会产生阶乘级复杂度,本算法诳骗「排列数字阶乘和固定」的数学性质,只校验独一候选sumFac,都备跳过排列成列。
四、时刻复杂度分析
1. 预解决阶乘(init)
固定轮回0~9,轮回次数恒定10次 → O(1) 常数时刻,只实施一次。
2. isDigitorialPermutation 里面两段数字遍历
设输入数字n的位数为k(题目上限1e9,最多10位):
• 遍历原数字n:最多10次轮回 O(k)=O(1);
• 遍历sumFac:单个数字阶乘最大9!=362880,10位数字总和上限 10*362880=3,628,800,最多7位数字,轮回次数最多7次 O(1);
• 数组相配对比:固定长度10的数组逐元素比拟,10次操作 O(1);
举座单次判断函数时刻:O(1),与输入数值大小无关。
全局总时刻复杂度:O(1)(常数级)。
五、额外空间复杂度分析
额外开拓的存储空间:
1. 全局fac数组:固定长度10,O(1);
2. 函数内cnt数组:固定长度10,O(1);
3. 局部变量sumFac、d、轮回计数器:单个int变量,常数空间;
不存在随输入长度增长的动态数组、切片、递归栈等。
总数外空间复杂度:O(1)(常数空间)。
Go无缺代码如下:
package main
import (
"fmt"
)
var fac = [10]int{1}
func init {
// 预解决阶乘
for i := 1; i
fac[i] = fac[i-1] * i
}
}
func isDigitorialPermutation(n int)bool {
sumFac := 0
cnt := [10]int{}
for ; n > 0; n /= 10 {
d := n % 10
sumFac += fac[d]
cnt[d]++
}
for ; sumFac > 0; sumFac /= 10 {
cnt[sumFac]--
}
// cnt[i] == 0
return cnt == [10]int{}
}
func main {
n := 145
result := isDigitorialPermutation(n)
fmt.Println(result)
}

Python无缺代码如下:
# -*-coding:utf-8-*-
# 预解决阶乘
fac = [1] * 10
for i in range(1, len(fac)):
fac[i] = fac[i-1] * i
def is_digitorial_permutation(n: int) -> bool:
sum_fac = 0
cnt = [0] * 10
# 经营诸君数字阶乘之和,并统计诸君数字出现次数
temp = n
while temp > 0:
d = temp % 10
sum_fac += fac[d]
cnt[d] += 1
temp //= 10
# 对阶乘和的诸君数字,减少对应计数
while sum_fac > 0:
cnt[sum_fac % 10] -= 1
sum_fac //= 10
# 查验整个计数是否为 0
return all(c == 0for c in cnt)
def main:
n = 145
result = is_digitorial_permutation(n)
print(result)
if __name__ == "__main__":
main

C++无缺代码如下:
#include
#include
using namespace std;
// 预解决阶乘
array fac;
void initFac {
fac[0] = 1;
for (int i = 1; i
fac[i] = fac[i-1] * i;
}
}
bool isDigitorialPermutation(int n) {
int sumFac = 0;
array cnt = {0};
// 经营诸君数字阶乘之和,并统计诸君数字出现次数
int temp = n;
while (temp > 0) {
int d = temp % 10;
sumFac += fac[d];
cnt[d]++;
temp /= 10;
}
// 对阶乘和的诸君数字,减少对应计数
while (sumFac > 0) {
cnt[sumFac % 10]--;
sumFac /= 10;
}
// 查验整个计数是否为 0
for (int i = 0; i
if (cnt[i] != 0) {
returnfalse;
}
}
returntrue;
}
int main {
initFac;
int n = 145;
bool result = isDigitorialPermutation(n);
百家乐2026世界杯中国官方下载cout
return0;
}

咱们笃信东谈主工智能为粗鄙东谈主提供了一种“增强器具”,并努力于于共享全认识的AI常识。在这里,您不错找到最新的AI科普著述、器具评测、训诫成果的阴私以及行业知悉。
接待怜惜“福大大架构师逐日一题”开运体育官方网站,发音尘可得到口试费力,让AI助力您的将来发展。

备案号: