[CareerCup][Google Interview] 找出最小排序次数
Given an unsorted array provide two indices n1 and n2 such that if we only sort the elements between n1 and n2,then the whole array will become sorted.
n1-n2 should be as minimum as possible.
http://www.careercup.com/question?id=4345015
参考上面一位大神的解答,非常精彩,不过理解起来有点费力。
Let A be the array and T = 0.
While A[T] <= A[T + 1] we increase T be one unit.Doing so , we find the longest increasing sequence from the start of the array.
Now, let P = T + 1. The idea is to find if after A[T] are elements smaller than it.
So , while(P < A.length && T >= 0) if(A[P] < A[T]) --T; else ++P;
After these operations, T will be actually n1, because we know that A[1..T] is increasing(from first step) and there is no element in the array smaller than A[T] after position T.
We use the same idea to find the longest increasing array that has A[A.length - 1].
To do so, let T2 = A.length - 1.While A[T2] >= A[T2 - 1] --T2.
Now we must find if in the rest of the array is a bigger element than the one in the A[T2]. We could go until position T found previously, and if there is a P so A[P] >= A[T2] we increase T2.Finally T2 will actually be n2. Time complexity O(N) and space complexity O(1). There are other solutions in O(N logN) time and O(1) space using sorting or O(N log N) time and O(N) space using heaps.
就是找出左边的上升序列,然后在它右边找有没有小于它的,然后不断缩小上升序列的区间,直到序列右边没有小于它的值。
对于右边也找出上升序列,然后往左边找有没有大于它的,然后也不断缩小上升序列的区间。
这样两个区间的中间就是要排序的最小区间了。
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 void solve(vector<int> &a) 6 { 7 int i = 0; 8 while(i < a.size() - 1) 9 { 10 if (a[i] <= a[i+1]) 11 i++; 12 else 13 break; 14 } 15 16 int k = i + 1; 17 18 while(i >= 0 && k < a.size()) 19 { 20 if (a[k] < a[i]) 21 i--; 22 else 23 k++; 24 } 25 26 int j = a.size() - 1; 27 28 while(j >= 1) 29 { 30 if (a[j-1] <= a[j]) 31 j--; 32 else 33 break; 34 } 35 36 k = j - 1; 37 38 while(k > i && j < a.size()) 39 { 40 if (a[k] > a[j]) 41 j++; 42 else 43 k--; 44 } 45 46 cout << i + 1 << ' ' << j - 1 << endl; 47 } 48 49 int main() 50 { 51 vector<int> a; 52 for(int i = 0; i < 10; i++) 53 a.push_back(i); 54 55 solve(a); 56 57 vector<int> b; 58 b.push_back(1); 59 b.push_back(2); 60 b.push_back(3); 61 b.push_back(5); 62 b.push_back(4); 63 64 solve(b); 65 66 vector<int> c; 67 for(int i = 10; i >= 1; i--) 68 c.push_back(i); 69 solve(c); 70 }