2023-12-30:用go语言,给你一个下标从 0 开始的整数数组 nums ,它包含 n 个 互不相同 的正整数, 如果 nums 的一个排列满足以下条件,我们称它是一个特别的排列。 对于 0 <
2023-12-30:用go语言,给你一个下标从 0 开始的整数数组 nums ,它包含 n 个 互不相同 的正整数,
如果 nums 的一个排列满足以下条件,我们称它是一个特别的排列。
对于 0 <= i < n - 1 的下标 i:
要么 nums[i] % nums[i+1] == 0,
要么 nums[i+1] % nums[i] == 0。
请你返回特别排列的总数目,由于答案可能很大,请将它对 1000000007 取余 后返回。
输入:nums = [2,3,6]。
输出:2。
来自力扣2741. 特别的排列。
答案2023-12-30:
来自左程云。
大体步骤如下:
1.在main函数中,我们调用了specialPerm函数,并传入nums数组。在这个函数内部,首先计算了nums数组的长度n,然后初始化了一个二维数组dp,用于记录状态的转移。
2.specialPerm函数返回调用process函数的结果,传入了nums、n、0、0和dp作为参数。
3.process函数用于计算满足特殊条件的排列总数。首先,它检查dp数组中是否已经计算了当前状态s和位置p的结果,如果是,则直接返回该结果。
4.接下来,如果状态s表示所有的数字都被使用过,那么将结果设为1,表示找到了一个满足条件的排列。
5.否则,对于给定位置p,遍历每个数字i,如果当前状态s中没有包含数字i,且a[p]能整除a[i]或者a[i]能整除a[p],则递归调用process函数,并将结果加到ans上。
6.最后,将得到的ans存入dp数组中,并返回结果。
整体的时间复杂度:O(n*2^n),其中n是nums数组的长度。对于process函数中的每个状态s以及位置p,最坏情况下都要回溯所有的n个数字,因此是指数级的复杂度。
额外空间复杂度:O(2^n * n),其中dp数组占据了主要的空间,它是一个大小为2^n * n的二维数组。
go完整代码如下:
package main
import "fmt"
var mod = 1000000007
func specialPerm(nums []int) int {
n := len(nums)
dp := make([][]int, 1<<n)
for i := range dp {
dp[i] = make([]int, n)
for j := range dp[i] {
dp[i][j] = -1
}
}
return process(nums, n, 0, 0, dp)
}
func process(a []int, n, s, p int, dp [][]int) int {
if dp[s][p] != -1 {
return dp[s][p]
}
var ans int
if s == (1<<n)-1 {
ans = 1
} else {
for i := 0; i < n; i++ {
if s == 0 || (s&(1<<i) == 0 && (a[p]%a[i] == 0 || a[i]%a[p] == 0)) {
ans = (ans + process(a, n, s|(1<<i), i, dp)) % mod
}
}
}
dp[s][p] = ans
return ans
}
func main() {
nums := []int{2, 3, 6}
result := specialPerm(nums)
fmt.Println("Result:", result)
}

rust完整代码如下:
fn special_perm(nums: Vec<i32>) -> i32 {
let n = nums.len();
let mod_num = 1000000007;
let mut dp = vec![vec![-1; n]; 1 << n];
process(&nums, n, 0, 0, &mut dp, mod_num)
}
fn process(a: &Vec<i32>, n: usize, s: usize, p: usize, dp: &mut Vec<Vec<i32>>, mod_num: i32) -> i32 {
if dp[s][p] != -1 {
return dp[s][p];
}
let ans: i32;
if s == (1 << n) - 1 {
ans = 1;
} else {
ans = (0..n).fold(0, |accum, i| {
if s == 0 || (s & (1 << i) == 0 && (a[p] % a[i] == 0 || a[i] % a[p] == 0)) {
(accum + process(a, n, s | (1 << i), i, dp, mod_num)) % mod_num
} else {
accum
}
});
}
dp[s][p] = ans;
ans
}
fn main() {
let nums = vec![2, 3, 6];
let result = special_perm(nums);
println!("Result: {}", result);
}

c++完整代码如下:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
const int mod = 1000000007;
int process(const vector<int>& a, int n, int s, int p, unordered_map<int, unordered_map<int, int>>& dp) {
if (dp.count(s) && dp[s].count(p) != 0) {
return dp[s][p];
}
int ans = 0;
if (s == (1 << n) - 1) {
ans = 1;
}
else {
for (int i = 0; i < n; i++) {
if (s == 0 || (s & (1 << i)) == 0 && (a[p] % a[i] == 0 || a[i] % a[p] == 0)) {
ans = (ans + process(a, n, s | (1 << i), i, dp)) % mod;
}
}
}
dp[s][p] = ans;
return ans;
}
int specialPerm(const vector<int>& nums) {
int n = nums.size();
unordered_map<int, unordered_map<int, int>> dp;
return process(nums, n, 0, 0, dp);
}
int main() {
vector<int> nums = { 2, 3, 6 };
int result = specialPerm(nums);
cout << "Result: " << result << endl;
return 0;
}

c完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MOD 1000000007
int process(int* a, int n, int s, int p, int** dp);
int specialPerm(int* nums, int numsSize) {
int n = numsSize;
int** dp = (int**)malloc((1 << n) * sizeof(int*));
for (int i = 0; i < (1 << n); i++) {
dp[i] = (int*)malloc(n * sizeof(int));
for (int j = 0; j < n; j++) {
dp[i][j] = -1;
}
}
return process(nums, n, 0, 0, dp);
}
int process(int* a, int n, int s, int p, int** dp) {
if (dp[s][p] != -1) {
return dp[s][p];
}
int ans = 0;
if (s == (1 << n) - 1) {
ans = 1;
}
else {
for (int i = 0; i < n; i++) {
if (s == 0 || ((s & (1 << i)) == 0 && (a[p] % a[i] == 0 || a[i] % a[p] == 0))) {
ans = (ans + process(a, n, s | (1 << i), i, dp)) % MOD;
}
}
}
dp[s][p] = ans;
return ans;
}
int main() {
int nums[] = { 2, 3, 6 };
int result = specialPerm(nums, sizeof(nums) / sizeof(nums[0]));
printf("Result: %d\n", result);
return 0;
}

2023-12-30:用go语言,给你一个下标从 0 开始的整数数组 nums ,它包含 n 个 互不相同 的正整数, 如果 nums 的一个排列满足以下条件,我们称它是一个特别的排列。 对于 0 <的更多相关文章
- 程序员之--C语言细节13(二维数组和指针,&*a[i][0]的理解,数组1[e]和e[1]非常可能你没见过)
主要内容:二维数组和指针.&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_C ...
- PAT 甲级 1144 The Missing Number (20 分)(简单,最后一个测试点没过由于开的数组没必要大于N)
1144 The Missing Number (20 分) Given N integers, you are supposed to find the smallest positive in ...
- 12天学好C语言——记录我的C语言学习之路(Day 10)
12天学好C语言--记录我的C语言学习之路 Day 10: 接着昨天的指针部分学习,有这么一个题目: //还是四个学生,四门成绩,只要有学生一门功课没及格就输出这个学生的所有成绩 /*//progra ...
- 12天学好C语言——记录我的C语言学习之路(Day 8)
12天学好C语言--记录我的C语言学习之路 Day 8: 从今天开始,我们获得了C语言中很有力的一个工具,那就是函数.函数的魅力不仅于此,一个程序到最后都是由众多函数组成的,我们一定要用好函数,用熟练 ...
- 12天学好C语言——记录我的C语言学习之路(Day 4)
12天学好C语言--记录我的C语言学习之路 Day 4: 首先来看一段程序: //输出下面4*5的矩阵 /* 1 2 3 4 5 2 4 6 8 10 3 6 9 12 ...
- 12天学好C语言——记录我的C语言学习之路(Day 3)
12天学好C语言--记录我的C语言学习之路 Day 3: 不知不觉到了第三天的学习,我们前两天学习的东西很杂乱,各个方面都有学习.我觉得这不是不系统,也不是学的不扎实,这种学习对于初学者而言我认为是很 ...
- 12天学好C语言——记录我的C语言学习之路(Day 2)
12天学好C语言--记录我的C语言学习之路 Day 2: 我建议大家每一天学习之前都仅凭记忆去敲前一天敲过的最后一个程序,或者敲前一天你认为最难最长的一个程序,如果一晚上的睡眠之后不看书还能敲的出来, ...
- 2015.12.29~2015.12.30真题回顾!-- HTML5学堂
2015.12.29~2015.12.30真题回顾!-- HTML5学堂 吃饭,能够解决饥饿,提供身体运作机能.练习就像吃饭,强壮自己,提升编程技能,寻求编程技巧的最佳捷径!吃饭不能停,练习同样不能停 ...
- 你可能不知道的30个Python语言的特点技巧
1 介绍 从我开始学习Python时我就决定维护一个经常使用的“窍门”列表.不论何时当我看到一段让我觉得“酷,这样也行!”的代码时(在一个例子中.在StackOverflow.在开源码软件中,等等), ...
- 12天学好C语言——记录我的C语言学习之路(Day 12)
12天学好C语言--记录我的C语言学习之路 Day 12: 进入最后一天的学习,用这样一个程序来综合考量指针和字符串的关系,写完这个程序,你对字符串和指针的理解应该就不错了. //输入一个字符串,内有 ...
随机推荐
- 在线问诊 Python、FastAPI、Neo4j — 创建 节点关系
目录 关系:症状-检查 关系:疾病-症状 代码重构 relationship_data.csv 症状,检查,疾病,药品,宜吃,忌吃 "上下楼梯疼,不能久站,感觉有点肿"," ...
- vue2实现饼图Pie组件封装
实现如下效果: 效果展示:https://code.juejin.cn/pen/7226656439941955644 如果不会请移步到官网的栗子,请点击查看 直接给大家上代码: 整体代码片段 1 & ...
- Spring扩展接口(1):ApplicationContextInitializer
在此系列文章中,我总结了Spring扩展接口,以及各个扩展点的使用场景.并整理出一个bean在spring中从被加载到初始化到销毁的所有可扩展点的顺序调用图.这样,我们也可以看到bean是如何一步步加 ...
- bash解释器特性、目录结构、命令种类及优先级、常用命令
bash解释器的交互式环境特性 命令和文件自动补全 注意:Tab只能补全命令和文件及其文件路径 [root@localhost ~]# ls /etc/sysconfig/network-script ...
- Go 复合类型之切片类型介绍
Go 复合类型之切片类型 目录 Go 复合类型之切片类型 一.引入 二.切片(Slice)概述 2.1 基本介绍 2.2 特点 2.3 切片与数组的区别 三. 切片声明与初始化 3.1 方式一:使用切 ...
- CF1746F Kazaee
prologue 数组范围一定要看好了开,不然容易我一样,调试调了一页多. 还有就是不要傻乎乎地只跑一次和哈希,因为和哈希(从下面地佬的题解中才知道)它其实算作是一种 trick(类比SA(Stimu ...
- Chrome Extensions v3 迁移清单
一.前置问题 1.1为什么需要迁移 v3? Chrome 计划完全停止 v2 版本维护,后续 v2 版本将无法上架谷歌插件商店,除此之外,未来新版本 Chrome 对于 v2 版本插件的限制会越来越大 ...
- DevOps2023现状报告|注重文化、以用户为中心是成功的关键
Google Cloud DORA 团队的一份新研究报告强调了企业文化和关注用户作为成功软件交付支柱的重要性. 2023 DevOps 状况报告分析了过去 9 年来通过此类最大规模调查收集的全球 36 ...
- 16.1 Socket 端口扫描技术
端口扫描是一种网络安全测试技术,该技术可用于确定对端主机中开放的服务,从而在渗透中实现信息搜集,其主要原理是通过发送一系列的网络请求来探测特定主机上开放的TCP/IP端口.具体来说,端口扫描程序将从指 ...
- Java中Synchronized的用法(转)
原文:http://blog.csdn.net/luoweifu/article/details/46613015 作者:luoweifu 转载请标名出处 <编程思想之多线程与多进程(1)--以 ...