需要排序的子数组
- 给定一个无序数组arr,求出需要排序的最短子数组长度
- 要求:
- O (N)
- 如输入:arr={2,3,7,5,4,6},返回4,因为只有{7,5,4,6}需要排序
- 如输入:arr={1,5,3,4,2,6,7},返回4,因为只有{5,3,4,2}需要排序
思路: 先从左到右遍历,先找大于max的并且赋值给max,如果有值小于max就p2=i,标记上,
再从右到左遍历,先找小于min的并且赋值给min,如果有值大于min就p1=i,标记上。
具体思路:
arr={1,5,3,4,2,6,7}
- 先从左到右遍历
{1,5,3,4,2,6,7}
,max = 1; // i = 0 value = 1{1,5,3,4,2,6,7}
,max = 5; // i = 1 value = 5{1,5,3,4,2,6,7}
,max = 5; p2 = 2 // i = 2 value = 3 < max{1,5,3,4,2,6,7}
,max = 5; p2 = 3 // i = 3 value = 4 < max{1,5,3,4,2,6,7}
,max = 5; p2 = 4 // i = 4 value = 2 < max{1,5,3,4,2,6,7}
,max = 6; // i = 5 value = 6{1,5,3,4,2,6,7}
,max = 7; // i = 6 value = 7- 再从右到左遍历
{1,5,3,4,2,6,7}
,min = 7; // i = 6 value = 7{1,5,3,4,2,6,7}
,min = 6; // i = 5 value = 6{1,5,3,4,2,6,7}
,min = 2; // i = 4 value = 2{1,5,3,4,2,6,7}
,min = 2; p1=3 // i = 3 value = 4{1,5,3,4,2,6,7}
,min = 2; p1=2 // i = 2 value = 3{1,5,3,4,2,6,7}
,min = 2; p1=1 // i = 1 value = 5{1,5,3,4,2,6,7}
,min = 1; // i = 0 value = 1
public class 需排序的子数组长度是多少 {
public static int[] findSegment(int[] A, int n) {
int p1 = -1;
int p2 = -1;
int max = A[0];
int min = A[n-1];
//扩展右端点:更新历史最高,只要右端点出现比历史最高低的,就应该将右边界扩展到此处
for (int i = 0; i < n; i++) {
// if (i < n - 1 && A[i] > A[i + 1] && p1 == -1) { //出现第一个拆点
// p1 = i;
if (A[i] > max) {
max = A[i];
}
// }
//只要低于历史高峰,就要扩展需要排序区间的右端点
if (A[i] < max)
p2 = i;
}
//找左端点:更新历史高峰,只要左侧出现比历史最低高的,就应该将左边界扩展到此处
for(int i = n - 1; i >= 0; i--) {
if (A[i] < min) {
min = A[i];
}
if (A[i] > min)
p1 = i;
}
if (p1 == -1) {
return new int[]{0, 0};
}
return new int[]{p1, p2};
//找左端点:更新历史高峰,只要左侧出现比历史最低高的,就应该将左边界扩展到此处
// for(int i = n - 1; i >= 0; i--) {
//
// if (A[i] < min) {
// min = A[i];
// }
// if (A[i] > min)
// p1 = i;
//
//
}
public static void main(String[] args){
int[] A = {1, 4, 6, 5, 9, 10};
int[] res = findSegment(A,6);
Util.print(res);
}
}
今晚睡觉,明天再写