当前位置: 首页 > news >正文

2026-04-06:字典序最小和为目标值且绝对值是排列的数组。用go语言,给你一个正整数 n 和一个整数 target。 你需要构造一个长度为 n 的整数数组,要求同时满足: 1.数组中所有元素的总

2026-04-06:字典序最小和为目标值且绝对值是排列的数组。用go语言,给你一个正整数 n 和一个整数 target。

你需要构造一个长度为 n 的整数数组,要求同时满足:

1.数组中所有元素的总和必须等于 target。

2.把数组里每个元素取绝对值以后,得到的这 n 个数必须是 1,2,…,n 的某种排列(也就是每个数 1 到 n 都恰好出现一次,顺序可以不同)。

3.若不存在满足上述条件的数组,则返回一个空数组 []。

另外,在所有满足条件的数组里,你要返回字典序最小的那个。

字典序比较规则:对任意两个数组 a 和 b,从左到右找到它们的第一个不同位置 i,如果 a[i] < b[i],则认为 a 的字典序小于 b。

因此,总波动值为 1 + 1 + 1 = 3。

1 <= n <= 100000。

-10000000000 <= target <= 10000000000。

输入: n = 3, target = 0。

输出: [-3,1,2]。

解释:

和为 0 且绝对值组成大小为 3 的排列的数组有:

[-3, 1, 2]

[-3, 2, 1]

[-2, -1, 3]

[-2, 3, -1]

[-1, -2, 3]

[-1, 3, -2]

[1, -3, 2]

[1, 2, -3]

[2, -3, 1]

[2, 1, -3]

[3, -2, -1]

[3, -1, -2]

字典序最小的是 [-3, 1, 2]。

题目来自力扣3752。

分步详细过程

我们以n=3,target=0为例,完整拆解解题的每一步逻辑,全程不写代码,只讲原理和操作。

第一步:判断是否存在合法数组

首先要确定有没有满足条件的数组,这是解题的前提,核心分3个小步骤:

  1. 计算1~n的总和最大值
    1到n所有数相加的总和是固定值,公式:总和 = n*(n+1)/2
    n=3时:1+2+3=6,这个值是所有元素全为正数时的总和,记为mx

  2. 判断target的数值范围是否合法
    数组元素是1~n加正负号,所以总和的最大值是mx(全正),最小值是-mx(全负)
    如果target > mx 或者 target < -mx,直接判定无合法数组。
    n=3,target=0:0在-6和6之间,范围合法。

  3. 判断奇偶性是否匹配
    我们把一个正数x改成负数-x,总和的变化是:减少了2x(总和 = 原总和 - 2x)。
    这意味着:原总和 - 目标值必须是偶数(因为是2的倍数),否则无法通过改符号得到target。
    公式:(mx - target) % 2 == 0 才合法。
    n=3,mx=6,target=0:6-0=6,6是偶数,奇偶性合法。

    ✅ 三个条件都满足,存在合法数组;任意一个不满足,直接返回空数组。

第二步:计算需要取负号的数字总和

这是核心计算步骤,目的是找到哪些数字需要加负号

  1. 设:需要取负号的数字的绝对值之和negS
  2. 推导公式:negS = (mx - target) / 2
    原理:原总和mx,每把一个数x变负,总和减2x,总共需要减mx-target,所以总负号数的和就是这个值的一半。
  3. 代入计算:n=3,mx=6,target=0 → negS=(6-0)/2=3。
    结论:我们需要从1、2、3中选若干个数,让它们的和等于3,这些数最终要变成负数。

第三步:确定哪些数字取负号(保证字典序最小)

字典序最小的规则:左边的数字尽可能小(优先用大负数),右边的数字尽可能大
因为负数 < 正数,所以要让数组字典序最小,必须左边优先放绝对值大的负数

操作规则:从最大的数字开始,依次尝试取负,直到选中的数字总和等于negS:

  1. 从n=3开始检查:3 ≤ 3(negS),选中3取负,剩余需要的和:3-3=0;
  2. 剩余需要的和为0,剩下的数字(2、1)都不取负,保持正数;
  3. 最终确定:只有数字3需要取负,1和2保持正数。

第四步:构造字典序最小的数组

按照「左边放负数,右边放正数,负数从大到小排,正数从小到大排」的规则填充数组:

  1. 数组长度为3,左指针从开头开始,右指针从末尾开始;
  2. 先把确定的负数(-3)放在最左侧(满足字典序最小);
  3. 剩下的正数(1、2)按从小到大的顺序,依次放在负数后面;
  4. 最终数组:[-3, 1, 2],和题目要求的输出完全一致。

时间复杂度与额外空间复杂度分析

1. 总时间复杂度

整个过程只做了一次从n到1的循环遍历,没有嵌套循环,也没有额外的递归/复杂操作。
循环次数等于n的值,因此时间复杂度为:O(n)
(n最大为100000,O(n)的效率完全满足题目要求)

2. 总额外空间复杂度

我们只创建了一个结果数组(存储最终答案),没有使用其他额外的数据结构(如栈、队列、哈希表等),也没有递归调用栈。
结果数组的长度等于n,因此额外空间复杂度为:O(n)
(如果不算结果数组的必要空间,额外辅助空间为O(1))


总结

  1. 解题分四大核心步骤:合法性判断 → 计算负号数字总和 → 选定负号数字 → 构造最小字典序数组;
  2. 时间复杂度:O(n)(线性遍历一次);
  3. 额外空间复杂度:O(n)(仅存储结果数组)。

Go完整代码如下:

packagemainimport("fmt")funclexSmallestNegatedPerm(nint,targetint64)[]int{t:=int(target)mx:=n*(n+1)/2ift>mx||-t>mx||(mx-t)%2!=0{returnnil}negS:=(mx-t)/2// 取负号的元素(的绝对值)之和ans:=make([]int,n)l,r:=0,n-1// 从 1,2,...,n 中选一些数,元素和等于 negS// 为了让负数部分的字典序尽量小,从大往小选forx:=n;x>0;x--{ifnegS>=x{negS-=x ans[l]=-x l++}else{// 大的正数填在末尾ans[r]=x r--}}returnans}funcmain(){n:=3target:=int64(0)result:=lexSmallestNegatedPerm(n,target)fmt.Println(result)}

Python完整代码如下:

# -*-coding:utf-8-*-fromtypingimportList,OptionaldeflexSmallestNegatedPerm(n:int,target:int)->Optional[List[int]]:t=target mx=n*(n+1)//2ift>mxor-t>mxor(mx-t)%2!=0:returnNonenegS=(mx-t)//2# 取负号的元素(的绝对值)之和ans=[0]*n l,r=0,n-1# 从 1,2,...,n 中选一些数,元素和等于 negS# 为了让负数部分的字典序尽量小,从大往小选forxinrange(n,0,-1):ifnegS>=x:negS-=x ans[l]=-x l+=1else:# 大的正数填在末尾ans[r]=x r-=1returnansdefmain():n=3target=0result=lexSmallestNegatedPerm(n,target)print(result)if__name__=="__main__":main()

C++完整代码如下:

#include<iostream>#include<vector>std::vector<int>*lexSmallestNegatedPerm(intn,longlongtarget){intt=static_cast<int>(target);intmx=n*(n+1)/2;if(t>mx||-t>mx||(mx-t)%2!=0){returnnullptr;}intnegS=(mx-t)/2;// 取负号的元素(的绝对值)之和std::vector<int>*ans=newstd::vector<int>(n);intl=0,r=n-1;// 从 1,2,...,n 中选一些数,元素和等于 negS// 为了让负数部分的字典序尽量小,从大往小选for(intx=n;x>0;x--){if(negS>=x){negS-=x;(*ans)[l]=-x;l++;}else{// 大的正数填在末尾(*ans)[r]=x;r--;}}returnans;}intmain(){intn=3;longlongtarget=0;std::vector<int>*result=lexSmallestNegatedPerm(n,target);if(result!=nullptr){std::cout<<"[";for(size_t i=0;i<result->size();i++){std::cout<<(*result)[i];if(i<result->size()-1)std::cout<<" ";}std::cout<<"]"<<std::endl;deleteresult;// 记得释放内存}else{std::cout<<"nil"<<std::endl;}return0;}

http://www.jsqmd.com/news/594591/

相关文章:

  • 告别‘看片难’:用HiFuse网络实战医学影像分类,从CT到病理图都能搞定
  • 智能能耗管理系统如何助力轨道交通实现绿色低碳运营
  • OpenClaw自动化测试:Qwen3.5-9B验证UI截图与需求文档一致性
  • 2026年半导体行业展会推荐:高价值半导体行业展会指南 - 品牌2026
  • 微信公众号授权获取code无限循环?3步搞定Vue项目中的重定向问题
  • Mac电脑免费小龙虾OpenClaw+Ollama使用心得
  • MPU9250磁力计读数为0?别慌,一个函数mpu_set_bypass(1)就能搞定
  • 千问3.5-27B镜像性能实测:OpenClaw任务执行效率对比
  • KL46Z电容触摸驱动库:TSI传感器适配与抗干扰实践
  • Ubuntu 相关设置
  • Texlive毕业设计实战:解决Font缺失的四种高效方案
  • 从API调用到完整应用:手把手教你用Dashscope和Streamlit搭建一个多模态聊天机器人
  • 星图GPU一键部署OpenClaw镜像:Qwen3.5-9B云端体验方案
  • 2026智能体AI元年:中国调用量首超美国,我们该恐慌还是兴奋?
  • OpenClaw+千问3.5-9B智能截图:自动识别图中文字信息
  • OpenClaw硬件优化:Qwen2.5-VL-7B在低配设备上的运行技巧
  • 网站页面加载速度对SEO有什么影响_什么是外链建设_外链对SEO有什么影响
  • OpenClaw批量处理技巧:Qwen3-14b_int4_awq同时处理多个文件任务
  • 风光负荷不同鲁棒性对系统总成本的影响研究(考虑上下备用容量)(Matlab代码实现)
  • OpenClaw备份与迁移:Gemma-3-12b-it模型配置快速转移指南
  • 2026AI智能体元年,中国正式超越美国
  • 如何在192G内存+4090显卡的台式机上高效部署1.73bit量化版DeepSeek
  • Java 搜索型数据结构全解:二叉搜索树、Map/Set 体系与哈希表
  • 某音抓包翻车实录:从Hook失败到稳定替换so的踩坑与修复指南
  • ARM单片机位带操作原理与应用详解
  • Python新手必看:从安装到第一个GUI程序的全流程指南(含IDLE使用技巧)
  • 储能和虚拟电厂越来越热,为什么真正决定收益的还是预测系统的可信度?
  • OpenClaw+千问3.5-9B自动化写作:技术博客大纲与初稿生成
  • 华为云SWR镜像仓库避坑指南:从6.9G到19G的‘膨胀’镜像,我是如何瘦身成功的
  • 从DH参数到3D动画:手把手教你用SimMechanics在Simulink里‘拼’出一个六轴机械臂