首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

2024-04-10:用go语言,考虑一个非负整数数组 A, 如果数组中相邻元素之和为完全平方数,我们称这个数组是正方形数组。

2024-04-10:用go语言,考虑一个非负整数数组 A,

如果数组中相邻元素之和为完全平方数,我们称这个数组是正方形数组。

现在要计算 A 的正方形排列的数量。

两个排列 A1 和 A2 被认为是不同的,如果存在至少一个索引 i,满足 A1[i] != A2[i]。

输出:2。

答案2024-04-10:

来自左程云。

灵捷3.5

大体过程如下:

1.定义变量和数据结构:

• 定义常量MAXN为 13,表示数组的最大长度。

• 定义全局变量f,存储阶乘的预计算结果。

2.编写初始化函数init():

• 创建长度为MAXN的切片f,并将其第一个元素初始化为 1。

• 使用循环计算并预存每个阶乘值。

3.编写函数numSquarefulPerms(nums []int) int来计算正方形排列的数量:

• 初始化变量n为数组nums的长度。

• 创建二维切片graph和dp,分别用于记录数字之间是否存在完全平方数关系和动态规划的状态。

• 遍历数组nums构建图graph,找出数字之间的完全平方数关系。

• 初始化变量ans为 0,用于记录正方形排列的数量。

• 使用深度优先搜索函数dfs()遍历图graph,并计算正方形排列的数量。

• 将数组nums进行排序,以便处理相同数字的情况。

• 使用变量start和end遍历排序后的数组nums,计算相同数字之间的排列数量,并更新结果。

• 返回最终的正方形排列数量。

4.编写深度优先搜索函数dfs(graph [][]int, i int, s int, n int, dp [][]int) int:

• 如果当前状态s表示所有元素都被使用,返回1,表示找到了一种满足条件的排列。

• 如果当前状态已经被计算过,直接返回对应的结果。

• 初始化变量ans为 0,用于记录满足条件的排列数量。

• 遍历与当前位置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)

• 动态规划的状态数组dp的空间复杂度为 O(n * 2^n),其中 n 是数组nums的长度。

• 构建图的辅助数组graph的空间复杂度为 O(n^2),其中 n 是数组nums的长度。

• 其他变量和数据结构的空间复杂度为 O(1)。

Go完整代码如下:

package main

import (

"fmt"

"math"

"sort"

)

var MAXN int = 13

var f []int

func init() {

f = make([]int, MAXN)

f[0] = 1

for i := 1; i < MAXN; i++ {

f[i] = i * f[i-1]

}

}

func numSquarefulPerms(nums []int) int {

n := len(nums)

graph := make([][]int, n)

dp := make([][]int, n)

for i := 0; i < n; i++ {

graph[i] = make([]int, 0)

dp[i] = make([]int, 1<<n)

for j := 0; j < 1<<n; j++ {

dp[i][j] = -1

}

}

for i := 0; i < n; i++ {

for j := i + 1; j < n; j++ {

s := int(math.Sqrt(float64(nums[i] + nums[j])))

if s*s == nums[i]+nums[j] {

graph[i] = append(graph[i], j)

graph[j] = append(graph[j], i)

}

}

}

ans := 0

for i := 0; i < n; i++ {

ans += dfs(graph, i, 1<<i, n, dp)

}

sort.Ints(nums)

start := 0

for end := 1; end < n; end++ {

if nums[start] != nums[end] {

ans /= f[end-start]

start = end

}

}

ans /= f[n-start]

return ans

}

func dfs(graph [][]int, i int, s int, n int, dp [][]int) int {

if s == (1<<n)-1 {

return 1

}

if dp[i][s] != -1 {

return dp[i][s]

}

ans := 0

for _, next := range graph[i] {

if s&(1<<next) == 0 {

ans += dfs(graph, next, s|(1<<next), n, dp)

}

}

dp[i][s] = ans

return ans

}

func main() {

nums := []int{1, 17, 8}

result := numSquarefulPerms(nums)

fmt.Println(result)

}

在这里插入图片描述Python完整代码如下:

# -*-coding:utf-8-*-

import math

from collections import defaultdict

MAXN = 13

f = [0] * MAXN

def init():

global f

f[0] = 1

for i in range(1, MAXN):

f[i] = i * f[i-1]

def numSquarefulPerms(nums):

n = len(nums)

graph = defaultdict(list)

dp = [[-1 for _ in range(1<<n)] for _ in range(n)]

for i in range(n):

for j in range(i + 1, n):

s = int((nums[i] + nums[j]) ** 0.5)

if s * s == nums[i] + nums[j]:

graph[i].append(j)

graph[j].append(i)

def dfs(i, s):

if s == (1<<n) - 1:

return 1

if dp[i][s] != -1:

return dp[i][s]

ans = 0

for next in graph[i]:

if s & (1 << next) == 0:

ans += dfs(next, s | (1 << next))

dp[i][s] = ans

return ans

ans = 0

for i in range(n):

ans += dfs(i, 1 << i)

nums.sort()

start = 0

for end in range(1, n):

if nums[start] != nums[end]:

ans //= f[end - start]

start = end

ans //= f[n - start]

return ans

init()

nums = [1, 17, 8]

result = numSquarefulPerms(nums)

print(result)

在这里插入图片描述

  • 发表于:
  • 原文链接https://page.om.qq.com/page/Ou6MrCFKIAU91OkWDrL51Mkw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

相关快讯

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券