执行结果:通过
执行用时和内存消耗如下:

代码如下:
int semiOrderedPermutation(int* nums, int numsSize) {int first = 0, last = 0;for (int i = 0; i < numsSize; i++) {if (nums[i] == 1) {first = i;}if (nums[i] == numsSize) {last = i;}}return first + numsSize - 1 - last - (last < first ? 1 : 0);
}
解题思路:
这段代码的目的是计算一个特定排列(称为半有序排列)的“调整”次数,使其变成完全有序的排列。具体思路如下:
- 初始化变量:
first用于记录数字1在数组中的位置。last用于记录数组最大值(即numsSize)在数组中的位置。
- 遍历数组:
- 遍历整个数组
nums,大小为numsSize。 - 在遍历过程中,更新
first和last的值。当遇到数字1时,更新first为当前索引i;当遇到数字等于数组大小numsSize时,更新last为当前索引i。
- 遍历整个数组
- 计算调整次数:
- 为了使数组完全有序,理想情况下
1应该位于第一个位置,而numsSize应该位于最后一个位置。 - 如果
1不在第一个位置,我们需要将其移动到第一个位置,这需要first次移动(如果1已经在第一个位置,则不需要移动)。 - 如果
numsSize不在最后一个位置,我们需要将其移动到最后一个位置,这需要numsSize - 1 - last次移动(因为从last位置到最后一个位置之间有numsSize - 1 - last个位置)。 - 还需要考虑
1和numsSize的相对位置:- 如果
last在first的左边(即last < first),在移动numsSize到最后一个位置之后,1前面会有一个空位,所以移动1到第一个位置时,实际上只需要将1向右移动first - 1次(因为numsSize已经占据了最后一个位置,所以不需要额外的一次移动来“腾出”最后一个位置给numsSize)。但这种情况下,我们之前计算移动numsSize时已经考虑了numsSize - 1 - last次,所以需要在总数中减去 1 来避免重复计算这次“腾出”位置的移动。 - 如果
last在first的右边或相同位置,则不需要额外处理,直接按照上述计算即可。
- 如果
- 为了使数组完全有序,理想情况下
- 返回结果:
- 返回
first + numsSize - 1 - last - (last < first ? 1 : 0),即1到第一个位置需要的移动次数加上numsSize到最后一个位置需要的移动次数,再根据1和numsSize的相对位置决定是否减去 1。
- 返回
综上所述,这段代码通过计算 1 和数组最大值(numsSize)到它们理想位置所需的最少移动次数,来得到使整个数组有序的“调整”次数。