首页 > 其他分享 >2024-04-10:用go语言,考虑一个非负整数数组 A, 如果数组中相邻元素之和为完全平方数,我们称这个数组是正方形数组。 现在要计算 A 的正方形排列的数量。 两个排列 A1 和 A2 被认为是

2024-04-10:用go语言,考虑一个非负整数数组 A, 如果数组中相邻元素之和为完全平方数,我们称这个数组是正方形数组。 现在要计算 A 的正方形排列的数量。 两个排列 A1 和 A2 被认为是

时间:2024-04-10 14:56:16浏览次数:15  
标签:排列 nums int graph 正方形 MAXN 数组

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

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

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

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

输入:[1,17,8]。

输出:2。

答案2024-04-10:

来自左程云

灵捷3.5

大体过程如下:

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 使用变量 startend 遍历排序后的数组 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)

在这里插入图片描述

标签:排列,nums,int,graph,正方形,MAXN,数组
From: https://www.cnblogs.com/moonfdd/p/18126016

相关文章

  • 全排列价值(数学问题)
     1importjava.util.*;23publicclassDemo1{4publicstaticvoidmain(String[]args){5Scannersc=newScanner(System.in);6longn;7n=sc.nextLong();8longres=n*(n-1)/2%998244353;9for(in......
  • 小美的数组操作(美团2024届秋招笔试第二场编程真题)
    题面核心思想可以从示例中看出当sum/n能够整除时我们选择平均数作为众数即可不能整除时也就表示着不可能让所有数相同那么我们可以舍弃掉一个数a记剩下的数集合为b那么当b需要+1或-1后可能会剩下一些数那么我们可以选择让a去执行相反操作从而不影响b中剩......
  • 力扣经典150题第十三题:除自身以外数组的乘积
    目录力扣经典150题第十三题:除自身以外数组的乘积1.简介2.问题分析3.解题思路方法一:左右乘积列表方法二:优化空间复杂度4.代码实现5.时间复杂度分析6.应用和扩展7.总结8.参考资料力扣经典150题第十三题:除自身以外数组的乘积1.简介本文介绍如何设计一个算......
  • Java入门基础知识第八课(数组)——冒泡排序、Arrays工具类
    前面二白讲了关于数组的概念、语法以及简单的输入输出,实际上关于数组的知识还有很多,接下来咱们讲一下冒泡排序以及一些常用的Arrays工具类,需要记忆的知识很多,而且容易混淆。一、冒泡排序简介(原理)升序为例:从头开始,每次比较相邻两数小的交换到前面每轮结束后最大的数交换到......
  • 最大连续子数组和的实现
    题目:最大连续子数组和求解问题一、背景:问题:给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为:Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n例如,当(a[1],a[2],a[3......
  • 从二维数组到一维数组——探索01背包问题的动态规划优化
    文章目录题目前知背包问题二维dp数组一、思路二、解题方法三、Code一维dp数组一、思路二、解题方法三、Code总结本文将继续上一篇博客爬楼梯之后继续讲解同样用到了动态规划的01背包问题在解决动态规划问题时,我们经常面临着空间复杂度的挑战。01背包问题是一个......
  • Offer必备算法23_两个数组dp_八道力扣题详解(由易到难)
    目录①力扣1143.最长公共子序列解析代码②力扣1035.不相交的线解析代码③力扣115.不同的子序列解析代码④力扣44.通配符匹配解析代码⑤力扣10.正则表达式匹配解析代码⑥力扣97.交错字符串解析代码⑦力扣712.两个字符串的最小ASCII删除和解析代码⑧力扣71......
  • js 常用数组函数 join() 拼接, push()尾部添加、pop()移除最后一项、shift()删除第一项
    js常用数组函数join()拼接,push()尾部添加、pop()移除最后一项、shift()删除第一项、unshift()头部添加、sort()小到大顺序排列、slice()截取获取新数组、splice()分隔截取数组、concat()连接、reverse()反转文章目录1.join()函数2.push()函数3.pop()函数4.sh......
  • 使用C语言函数对数组进行操作
        前言       在我们了解数组和函数之后,我们对数组和函数进行结合,之后完成一些操作吧    题目描述    杰克想将函数与数组结合进行一些操作,以下是他想要达到的效果,请你帮帮他吧!    创建一个整型数组,完成对数组的操作   ......
  • LeetCode题练习与总结:排列序列--60
    一、题目描述给出集合 [1,2,3,...,n],其所有元素共有 n!种排列。按大小顺序列出所有排列情况,并一一标记,当 n=3时,所有排列如下:"123""132""213""231""312""321"给定 n和 k,返回第 k 个排列。示例1:输入:n=3,k=3输出:"213"示例2:输入:n=4,k=......