难度中等117收藏分享切换为英文接收动态反馈
给定一个整数数组,编写一个函数,找出索引m
和n
,只要将索引区间[m,n]
的元素排好序,整个数组就是有序的。注意:n-m
尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n]
,若不存在这样的m
和n
(例如整个数组是有序的),请返回[-1,-1]
。
示例:
输入: [1,2,4,7,10,11,7,12,6,7,16,18,19] 输出: [3,9]
提示:
0 <= len(array) <= 1000000
题解:
关于这道题,我姑且先这么理解:在一个数组中,有一处的连续的几个元素是无序的,只要将这个一段无序的子数组排序,就能使得整个数组有序。
有以下几种情况:
1、在这个数组中,只有一处无序,将这处无序的子数组排列后得到一个完整的有序数组。
2、在这个数组中有多个无序的地方,假设有三段无序的子数组,那么从第一个无序的头部到第三个无序的尾部都需要被重新排序以适应整体的递增或递减趋势
3、在这个数组中完全无序,那么就要从头到尾排序
4、这已经是个有序数组,那么就直接返回[-1,-1]
*又想到一种情况,就是,有一个具有10个元素的数组,前三个是连续递增、后七个是连续递减,那么如果按照顺序查找的话,会将后七个当做要修改重排的“无序数组”,但实际上,将前三个连续递增的改成连续递减的才符合,题目中最短子序列的要求。(又看了评论区,发现好像是默认升序。。。那就没有考虑这个的必要了(可是这样就似乎失去了找到最短序列的意义))
双指针,从左右两边向中间遍历,因为是默认的递增顺序,所以左边的指针要找到,其右边有比自身小的位置,右边的指针要找到左边有比自身大的位置。
/**
* @param {number[]} array
* @return {number[]}
*/
const array = [1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19];
var subSort = function (array) {
let rightt = -1;
let leftt = -1;
let max = Number.MIN_SAFE_INTEGER;
let min = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < array.length; i++) {
if (array[i] >= max) {
max = array[i];
} else {
rightt = i; //如果有比max小的情况,就移动右指针
}
if (array[array.length - 1 - i] <= min) {
min = array[array.length - 1 - i];
} else {
leftt = array.length - 1 - i;
}
}
return [leftt, rightt];
};
subSort(array);