题目:
We have some permutation A
of [0, 1, ..., N - 1]
, where N
is the length of A
.
The number of (global) inversions is the number of i < j
with 0 <= i < j < N
and A[i] > A[j]
.
The number of local inversions is the number of i
with 0 <= i < N
and A[i] > A[i+1]
.
Return true
if and only if the number of global inversions is equal to the number of local inversions.
Example 1:
Input: A = [1,0,2] Output: true Explanation: There is 1 global inversion, and 1 local inversion.
Example 2:
Input: A = [1,2,0] Output: false Explanation: There are 2 global inversions, and 1 local inversion.
Note:
A
will be a permutation of[0, 1, ..., A.length - 1]
.A
will have length in range[1, 5000]
.- The time limit for this problem has been reduced.
思路:
这道题目的难度实际上在于如何快速地计算global inversions。我们采用的方法有点类似于插入排序,就是逆序地将A中的元素依次加入一个有序集合中,每次加入一个元素后,计算它前面有多少个元素。由于处在它前面的每个元素和它本身在原来的A中都构成了逆序,所以我们累计每次插入一个元素后它前面的元素数量,就可以得到整个A数组中的全局逆序对数。
之后再顺序扫描一遍,得到local inversion,返回他俩是否一样就可以了。算法的空间复杂度是O(n),时间复杂度是O(nlogn),小于暴力法所需要的O(n^2)。
代码:
class Solution {
public:
bool isIdealPermutation(vector<int>& A) {
set<int> s;
int size = A.size();
int global = 0, local = 0;
for (int i = size - 1; i >= 0; --i) {
set<int>::iterator it = s.insert(A[i]).first;
global += distance(s.begin(), it);
}
for (int i = 0; i + 1 < size; ++i) {
local += A[i] > A[i + 1];
}
return global == local;
}
};