[CTCI] 最小调整有序

最小调整有序

题目描述

有一个整数数组,请编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的。注意:n-m应该越小越好,也就是说,找出符合条件的最短序列。

给定一个int数组A和数组的大小n,请返回一个二元组,代表所求序列的起点和终点。(原序列位置从0开始标号,若原序列有序,返回[0,0])。保证A中元素均为正整数。

测试样例:
[1,4,6,5,9,10],6
返回:[2,3]


先分别找到左边第一对逆序对与右边第一对逆序对,然后找出两个逆序对之间的最大值与最小值,然后分别向两边扩展边界到最小值与最大值。

 1 class Rearrange {
 2 public:
 3     int findEndOfLeft(vector<int> &A) {
 4         for (int i = 0; i < A.size(); ++i) {
 5             if (A[i] < A[i-1]) return i - 1;
 6         }
 7         return A.size() - 1;
 8     }
 9     int findStartOfRight(vector<int> &A) {
10         for (int i = A.size() - 2; i >= 0; --i) {
11             if (A[i] > A[i+1]) return i + 1;
12         }
13         return 0;
14     }
15     int shrinkLeft(vector<int> &A, int min_idx, int start) {
16         int comp = A[min_idx];
17         for (int i = start - 1; i >= 0; --i) {
18             if (A[i] <= comp) return i + 1;
19         }
20         return 0;
21     }
22     int shrinkRight(vector<int> &A, int max_idx, int start) {
23         int comp = A[max_idx];
24         for (int i = start; i < A.size(); ++i) {
25             if (A[i] >= comp) return i - 1;
26         }
27         return A.size() - 1;
28     }
29     vector<int> findSegment(vector<int> A, int n) {
30         // write code here
31         int end_left = findEndOfLeft(A);
32         int start_right = findStartOfRight(A);
33         int min_idx = end_left + 1;
34         if (min_idx >= A.size()) return {0, 0};
35         int max_idx = start_right - 1;
36         for (int i = end_left; i <= start_right; ++i) {
37             if (A[i] < A[min_idx]) min_idx = i;
38             if (A[i] > A[max_idx]) max_idx = i;
39         }
40         int left_idx = shrinkLeft(A, min_idx, end_left);
41         int right_idx = shrinkRight(A, max_idx, start_right);
42         return {left_idx, right_idx};
43     }
44 };

 

 


posted @ 2015-09-20 22:41  Eason Liu  阅读(471)  评论(0编辑  收藏  举报