2024-04-10:用go语言,考虑一个非负整数数组 A,
如果数组中相邻元素之和为完全平方数,我们称这个数组是正方形数组。
现在要计算 A 的正方形排列的数量。
两个排列 A1 和 A2 被认为是不同的,如果存在至少一个索引 i,满足 A1[i] != A2[i]。
输入:[1,17,8]。
输出:2。
答案2024-04-10:
来自左程云。
灵捷3.5
大体过程如下:
1.定义变量和数据结构:
- •定义常量为 13,表示数组的最大长度。
- MAXN
- •定义全局变量,存储阶乘的预计算结果。
- f
2.编写初始化函数:
init()
- •创建长度为的切片,并将其第一个元素初始化为 1。
- MAXN
- f
- •使用循环计算并预存每个阶乘值。
3.编写函数来计算正方形排列的数量:
numSquarefulPerms(nums []int) int
- •初始化变量为数组的长度。
- n
- nums
- •创建二维切片和,分别用于记录数字之间是否存在完全平方数关系和动态规划的状态。
- graph
- dp
- •遍历数组构建图,找出数字之间的完全平方数关系。
- nums
- graph
- •初始化变量为 0,用于记录正方形排列的数量。
- ans
- •使用深度优先搜索函数遍历图,并计算正方形排列的数量。
- dfs()
- graph
- •将数组进行排序,以便处理相同数字的情况。
- nums
- •使用变量和遍历排序后的数组,计算相同数字之间的排列数量,并更新结果。
- start
- end
- nums
- •返回最终的正方形排列数量。
4.编写深度优先搜索函数:
dfs(graph [][]int, i int, s int, n int, dp [][]int) int
- •如果当前状态表示所有元素都被使用,返回1,表示找到了一种满足条件的排列。
- s
- •如果当前状态已经被计算过,直接返回对应的结果。
- •初始化变量为 0,用于记录满足条件的排列数量。
- ans
- •遍历与当前位置相邻的下一个位置:
- i
- next
- •如果下一个位置还未被包含在当前状态中,将其加入到状态中,并递归调用继续搜索。
- next
- s
- s
- dfs()
- •将递归调用的结果累加到变量中。
- ans
- •将结果存储到中,并返回。
- dp
5.在函数中调用,传入示例数据,并打印结果。
main()
numSquarefulPerms()
[1, 17, 8]
总的时间复杂度:O(n * n!)
- •预计算阶乘的时间复杂度为 O(MAXN) = O(1),因为 MAXN 是常数。
- •构建图和计算正方形排列的数量的时间复杂度为 O(n!),其中 n 是数组的长度。
- nums
- •数组排序的时间复杂度为 O(n * logn),其中 n 是数组的长度。
- nums
总的空间复杂度:O(n * 2^n)
- •动态规划的状态数组的空间复杂度为 O(n * 2^n),其中 n 是数组的长度。
- dp
- nums
- •构建图的辅助数组的空间复杂度为 O(n^2),其中 n 是数组的长度。
- graph
- nums
- •其他变量和数据结构的空间复杂度为 O(1)。
Go完整代码如下:
packagemain
import(
"fmt"
"math"
"sort"
)
varMAXNint=13
varf[]int
funcinit(){
f=make([]int,MAXN)
f[0]=1
fori:=1;if[i]=i*f[i-1]
}
}
funcnumSquarefulPerms(nums[]int)int{
n:=len(nums)
graph:=make([][]int,n)
dp:=make([][]int,n)
fori:=0;igraph[i]=make([]int,0)
dp[i]=make([]int,1<forj:=0;j<1<dp[i][j]=-1
}
}
fori:=0;iforj:=i+1;js:=int(math.Sqrt(float64(nums[i]+nums[j])))
ifs*s==nums[i]+nums[j]{
graph[i]=append(graph[i],j)
graph[j]=append(graph[j],i)
}
}
}
ans:=0
fori:=0;ians+=dfs(graph,i,1<}
sort.Ints(nums)
start:=0
forend:=1;endifnums[start]!=nums[end]{
ans/=f[end-start]
start=end
}
}
ans/=f[n-start]
returnans
}
funcdfs(graph[][]int,iint,sint,nint,dp[][]int)int{
ifs==(1<return1
}
ifdp[i][s]!=-1{
returndp[i][s]
}
ans:=0
for_,next:=rangegraph[i]{
ifs&(1<ans+=dfs(graph,next,s|(1<}
}
dp[i][s]=ans
returnans
}
funcmain(){
nums:=[]int{1,17,8}
result:=numSquarefulPerms(nums)
fmt.Println(result)
}
Python完整代码如下:
#-*-coding:utf-8-*-
importmath
fromcollectionsimportdefaultdict
MAXN=13
f=[0]*MAXN
definit():
globalf
f[0]=1
foriinrange(1,MAXN):
f[i]=i*f[i-1]
defnumSquarefulPerms(nums):
n=len(nums)
graph=defaultdict(list)
dp=[[-1for_inrange(1<
foriinrange(n):
forjinrange(i+1,n):
s=int((nums[i]+nums[j])**0.5)
ifs*s==nums[i]+nums[j]:
graph[i].append(j)
graph[j].append(i)
defdfs(i,s):
ifs==(1<return1
ifdp[i][s]!=-1:
returndp[i][s]
ans=0
fornextingraph[i]:
ifs&(1<ans+=dfs(next,s|(1<dp[i][s]=ans
returnans
ans=0
foriinrange(n):
ans+=dfs(i,1<
nums.sort()
start=0
forendinrange(1,n):
ifnums[start]!=nums[end]:
ans//=f[end-start]
start=end
ans//=f[n-start]
returnans
init()
nums=[1,17,8]
result=numSquarefulPerms(nums)
print(result)
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.