-
我们首先分析题目,由题意知,我们只需要排序中间部分元素即可。
然而,左边和右边应该分别是两个单调增的序列 -
当找出左边和右边的递增序列时,我们不能确定它是否在整个数组中位置保持不变。
所以我们需要,找出中间序列的最大值以及最小值,再和左边序列的最大值一次比较,再和右边序列的最小值一次比较 -
如果左边序列的最大值比中间序列的最小值要大,那么我们将左边序列长度-1,再去确认是否需要更新中间序列的最大值;
-
如果右边序列的最小值 < 中间序列的最大值,那么我们将右边序列的长度-1,再去确认是否需要更新中间序列的最小值;
代码可能看起来较长,但思路极其简单:
int* subSort(int* array, int arraySize, int* returnSize){
int *ans = (int *)malloc(sizeof(int)*2);
if(arraySize <= 1){
ans[0] = -1;
ans[1] = -1;
*returnSize = 2;
return ans;
}
//求左边递增序列,和右边递增序列
int ll,rr,i;
bool find = false;//确认是否为已经排好序的数组
int base = array[0];
for(i = 1; i < arraySize; i++){
if(array[i] >= base){
base = array[i];
}else{
ll = i - 1;
find = true;
break;
}
}
if(!find){
ans[0] = -1;
ans[1] = -1;
*returnSize = 2;
return ans;
}
base = array[arraySize - 1];
for(i = arraySize - 2; i >= 0; i--){
if(array[i] <= base){
base = array[i];
}else{
rr = i + 1;
break;
}
}
//现在我们要找中间序列的最大值和最小值
int max = array[ll+1];
int min = array[ll+1];
for(i = ll + 2; i < rr; i++){
if(array[i] > max){
max = array[i];
}
if(array[i] < min){
min = array[i];
}
}
//看左递增序列的最大值是否比中间序列的最小值小
for(i = ll; i >= 0; i--){
if(array[i] > min){
ll--;
if(max < array[i]){
max = array[i];
}
}else{
break;
}
}
for(i = rr; i < arraySize; i++){
if(array[i] < max){
rr++;
if(array[i] < min){
min = array[i];
}
}else{
break;
}
}
ans[0] = ll + 1;
ans[1] = rr - 1;
*returnSize = 2;
return ans;
}