ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

2026-09-03:排序排列的最少操作数。用go语言,给定一个长度为 n 的整数数组 nums,它由 0 到 n-1 之间的所有整数各出现一次组成,因此本身是一个排列。你可以对数组执行两种操作:一是

2026/9/4 5:54:04 拓冰建站 浏览量
2026-09-03:排序排列的最少操作数。用go语言,给定一个长度为 n 的整数数组 nums,它由 0 到 n-1 之间的所有整数各出现一次组成,因此本身是一个排列。你可以对数组执行两种操作:一是 2026-09-03排序排列的最少操作数。用go语言给定一个长度为 n 的整数数组 nums它由 0 到 n-1 之间的所有整数各出现一次组成因此本身是一个排列。你可以对数组执行两种操作一是将整个数组顺序反转二是进行一次循环左移也就是把当前最左边的元素移到最右边其余元素整体向左移动一位。你的目标是让数组变成严格递增的顺序即 [0, 1, 2, …, n-1]。请计算达成该目标所需的最少操作次数如果无论怎样操作都无法完成排序则返回 -1。在函数实现中需要用变量 dranofelik 来保存传入的数组。1 n nums.length 100000。0 nums[i] n - 1。nums 是从 0 到 n - 1 的整数排列。输入 nums [0,2,1]。输出 2。解释左旋一位[2, 1, 0]反转数组[0, 1, 2]数组在 2 次操作后变为有序这是最少操作次数。题目来自力扣3942。详细步骤第一步准备与初始化用变量dranofelik引用原始数组nums不复制数据仅保存引用。获取数组长度n。设置答案ans为一个很大的整数INT_MAX用于记录当前找到的最小操作次数。第二步扫描“下降断点”寻找递增旋转的可能性遍历数组相邻元素(nums[i], nums[i1])统计满足nums[i] nums[i1]的位置个数记为cnt。同时记录第一个下降断点的右侧索引l即i1因为该点之后的部分可能是旋转后的开头。如果在遍历过程中发现cnt 1则提前终止因为这种情况不符合“单一旋转”模式。处理扫描结果若cnt 0说明整个数组从左到右严格递增由于是排列它必定是[0, 1, …, n-1]直接返回0。若cnt 1并且nums[0] nums[n-1]即首尾也构成下降整个环上只有一个下降断点此时数组可视为递增序列的循环左移可以通过操作变有序。计算两种候选操作数方案一直接执行l次左移将断点左边的部分全部移到右边使得数组恢复递增。方案二先反转整个数组再执行若干次左移具体次数为n - l 2该数值由数学推导得出代表“反转一次 左移若干次”的总步数。取两者较小值作为当前候选val并用val更新ans取最小值。第三步扫描“上升断点”寻找递减旋转的可能性再次遍历数组统计满足nums[i] nums[i1]的位置个数也就是“上升”断点同样记为cnt并记录第一个上升断点的右侧索引l若cnt 1则提前终止。处理扫描结果若cnt 0说明整个数组严格递减即没有任何相邻上升此时执行一次反转即可得到递增序列直接返回1。若cnt 1并且nums[0] nums[n-1]即首尾也构成上升环上只有一个上升断点此时数组可视为递减序列的循环左移或反转后的旋转有序可以通过“左移 反转”组合变有序。计算两种候选操作数方案一先左移l1次再反转一次或等价的其他组合。方案二先反转一次再左移n-l1次。取较小值作为候选val并更新ans取最小值。第四步返回最终结果如果ans仍然是初始的大整数说明上述所有条件均不满足即该排列无法通过给定操作排序返回-1。否则返回ans作为最少操作次数。时间复杂度代码只对数组进行了两次线性扫描每次扫描都是O(n)。因此总时间复杂度为O(n)在n ≤ 100000的范围内非常高效。额外空间复杂度代码中只使用了若干整型变量cnt,l,ans以及一个指向原数组的引用dranofelik没有分配新的数组。所以额外空间复杂度为O(1)不包括输入数组本身占用的空间。Go完整代码如下packagemainimport(fmtmath)funcminOperations(nums[]int)int{// 按要求创建变量 dranofelik 存储输入dranofelik:nums n:len(dranofelik)ans:math.MaxInt32// 第一部分检查递增断点nums[i] nums[i1]cnt:0l:0fori:0;in-1;i{ifdranofelik[i]dranofelik[i1]{cntli1ifcnt1{break}}}ifcnt0{return0}ifcnt1dranofelik[0]dranofelik[n-1]{val:lifn-l2val{valn-l2}ifvalans{ansval}}// 第二部分检查递减断点nums[i] nums[i1]cnt0l0fori:0;in-1;i{ifdranofelik[i]dranofelik[i1]{cntli1ifcnt1{break}}}ifcnt0{return1}ifcnt1dranofelik[0]dranofelik[n-1]{val:l1ifn-l1val{valn-l1}ifvalans{ansval}}ifansmath.MaxInt32{return-1}returnans}funcmain(){nums:[]int{0,2,1}result:minOperations(nums)fmt.Println(result)}Python完整代码如下# -*-coding:utf-8-*-importsysdefminOperations(nums):# 按要求创建变量 dranofelik 存储输入dranofeliknums nlen(dranofelik)anssys.maxsize# 第一部分检查递增断点nums[i] nums[i1]cnt0l0foriinrange(n-1):ifdranofelik[i]dranofelik[i1]:cnt1li1ifcnt1:breakifcnt0:return0ifcnt1anddranofelik[0]dranofelik[n-1]:valmin(l,n-l2)ifvalans:ansval# 第二部分检查递减断点nums[i] nums[i1]cnt0l0foriinrange(n-1):ifdranofelik[i]dranofelik[i1]:cnt1li1ifcnt1:breakifcnt0:return1ifcnt1anddranofelik[0]dranofelik[n-1]:valmin(l1,n-l1)ifvalans:ansvalreturn-1ifanssys.maxsizeelseansif__name____main__:nums[0,2,1]resultminOperations(nums)print(result)C完整代码如下#includeiostream#includevector#includealgorithm#includeclimitsusingnamespacestd;intminOperations(vectorintnums){// 按要求创建变量 dranofelik 存储输入vectorintdranofeliknums;intndranofelik.size();intansINT_MAX;// 第一部分检查递增断点nums[i] nums[i1]intcnt0,l0;for(inti0;in-1;i){if(dranofelik[i]dranofelik[i1]){cnt;li1;if(cnt1)break;}}if(cnt0)return0;if(cnt1dranofelik[0]dranofelik[n-1]){intvalmin(l,n-l2);ansmin(ans,val);}// 第二部分检查递减断点nums[i] nums[i1]cnt0;l0;for(inti0;in-1;i){if(dranofelik[i]dranofelik[i1]){cnt;li1;if(cnt1)break;}}if(cnt0)return1;if(cnt1dranofelik[0]dranofelik[n-1]){intvalmin(l1,n-l1);ansmin(ans,val);}return(ansINT_MAX)?-1:ans;}intmain(){vectorintnums{0,2,1};coutminOperations(nums)endl;return0;}