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

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[i+1]),统计满足nums[i] > nums[i+1]的位置个数,记为cnt
  • 同时记录第一个下降断点的右侧索引l(即i+1),因为该点之后的部分可能是旋转后的开头。
  • 如果在遍历过程中发现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[i+1]的位置个数(也就是“上升”断点),同样记为cnt,并记录第一个上升断点的右侧索引l,若cnt > 1则提前终止。

处理扫描结果:

  • cnt == 0:说明整个数组严格递减(即没有任何相邻上升),此时执行一次反转即可得到递增序列,直接返回1
  • cnt == 1并且nums[0] < nums[n-1](即首尾也构成上升,环上只有一个上升断点):
    • 此时数组可视为递减序列的循环左移(或反转后的旋转有序),可以通过“左移 + 反转”组合变有序。
    • 计算两种候选操作数:
      • 方案一:先左移l+1次,再反转一次(或等价的其他组合)。
      • 方案二:先反转一次,再左移n-l+1次。
    • 取较小值作为候选val,并更新ans(取最小值)。
第四步:返回最终结果
  • 如果ans仍然是初始的大整数,说明上述所有条件均不满足,即该排列无法通过给定操作排序,返回-1
  • 否则,返回ans作为最少操作次数。

时间复杂度

  • 代码只对数组进行了两次线性扫描,每次扫描都是O(n)
  • 因此总时间复杂度为O(n),在n ≤ 100000的范围内非常高效。

额外空间复杂度

  • 代码中只使用了若干整型变量(cnt,l,ans)以及一个指向原数组的引用dranofelik没有分配新的数组
  • 所以额外空间复杂度为O(1)(不包括输入数组本身占用的空间)。

Go完整代码如下:

packagemainimport("fmt""math")funcminOperations(nums[]int)int{// 按要求创建变量 dranofelik 存储输入dranofelik:=nums n:=len(dranofelik)ans:=math.MaxInt32// 第一部分:检查递增断点(nums[i] > nums[i+1])cnt:=0l:=0fori:=0;i<n-1;i++{ifdranofelik[i]>dranofelik[i+1]{cnt++l=i+1ifcnt>1{break}}}ifcnt==0{return0}ifcnt==1&&dranofelik[0]>dranofelik[n-1]{val:=lifn-l+2<val{val=n-l+2}ifval<ans{ans=val}}// 第二部分:检查递减断点(nums[i] < nums[i+1])cnt=0l=0fori:=0;i<n-1;i++{ifdranofelik[i]<dranofelik[i+1]{cnt++l=i+1ifcnt>1{break}}}ifcnt==0{return1}ifcnt==1&&dranofelik[0]<dranofelik[n-1]{val:=l+1ifn-l+1<val{val=n-l+1}ifval<ans{ans=val}}ifans==math.MaxInt32{return-1}returnans}funcmain(){nums:=[]int{0,2,1}result:=minOperations(nums)fmt.Println(result)}

Python完整代码如下:

# -*-coding:utf-8-*-importsysdefminOperations(nums):# 按要求创建变量 dranofelik 存储输入dranofelik=nums n=len(dranofelik)ans=sys.maxsize# 第一部分:检查递增断点(nums[i] > nums[i+1])cnt=0l=0foriinrange(n-1):ifdranofelik[i]>dranofelik[i+1]:cnt+=1l=i+1ifcnt>1:breakifcnt==0:return0ifcnt==1anddranofelik[0]>dranofelik[n-1]:val=min(l,n-l+2)ifval<ans:ans=val# 第二部分:检查递减断点(nums[i] < nums[i+1])cnt=0l=0foriinrange(n-1):ifdranofelik[i]<dranofelik[i+1]:cnt+=1l=i+1ifcnt>1:breakifcnt==0:return1ifcnt==1anddranofelik[0]<dranofelik[n-1]:val=min(l+1,n-l+1)ifval<ans:ans=valreturn-1ifans==sys.maxsizeelseansif__name__=="__main__":nums=[0,2,1]result=minOperations(nums)print(result)

C++完整代码如下:

#include<iostream>#include<vector>#include<algorithm>#include<climits>usingnamespacestd;intminOperations(vector<int>&nums){// 按要求创建变量 dranofelik 存储输入vector<int>dranofelik=nums;intn=dranofelik.size();intans=INT_MAX;// 第一部分:检查递增断点(nums[i] > nums[i+1])intcnt=0,l=0;for(inti=0;i<n-1;++i){if(dranofelik[i]>dranofelik[i+1]){++cnt;l=i+1;if(cnt>1)break;}}if(cnt==0)return0;if(cnt==1&&dranofelik[0]>dranofelik[n-1]){intval=min(l,n-l+2);ans=min(ans,val);}// 第二部分:检查递减断点(nums[i] < nums[i+1])cnt=0;l=0;for(inti=0;i<n-1;++i){if(dranofelik[i]<dranofelik[i+1]){++cnt;l=i+1;if(cnt>1)break;}}if(cnt==0)return1;if(cnt==1&&dranofelik[0]<dranofelik[n-1]){intval=min(l+1,n-l+1);ans=min(ans,val);}return(ans==INT_MAX)?-1:ans;}intmain(){vector<int>nums={0,2,1};cout<<minOperations(nums)<<endl;return0;}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询