0775. Global and Local Inversions (M)
Global and Local Inversions (M)
题目
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.
题意
给定一个数组,如果 i < j 且 A[i] > A[j],则称存在一个全局倒置;如果 A[i] > A[i+1],则称存在一个局部倒置。判断全局倒置的数量是否和局部倒置相同。
思路
最直接的方法是计算局部倒置和全局倒置(归并排序中判断),并进行比较。
用到题目给的条件:A是 0 ~ N-1 的一个排列,如果不存在倒置,A = [0, 1, 2, 3, ..., N-1],如果存在倒置,相当于在这个递增数组中选两个元素互换。局部倒置一定是全局倒置,如果两者数量相等,则所有全局倒置也一定是局部倒置,相当于在这个递增数组中仅选取相邻的元素进行互换,因此只要遍历一遍数组,判断 A[i] 的值是否在 (i - 1, i, i + 1)中即可。
代码实现
Java
直接计算
class Solution {
public boolean isIdealPermutation(int[] A) {
return calcLocal(A) == calcGlobal(A);
}
private int calcLocal(int[] A) {
int local = 0;
for (int i = 0; i < A.length - 1; i++) {
if (A[i] > A[i + 1]) {
local++;
}
}
return local;
}
private int calcGlobal(int[] A) {
int global = 0;
for (int step = 1; step < A.length; step *= 2) {
for (int start = 0; start + step < A.length; start += 2 * step) {
int left = start, leftEnd = left + step - 1;
int right = start + step, rightEnd = Math.min(A.length - 1, right + step - 1);
int[] tmp = new int[rightEnd - left + 1];
int index = 0;
while (left <= leftEnd || right <= rightEnd) {
if (left > leftEnd || right > rightEnd) {
tmp[index++] = left > leftEnd ? A[right++] : A[left++];
} else if (A[left] <= A[right]){
tmp[index++] = A[left++];
} else {
global += leftEnd - left + 1;
tmp[index++] = A[right++];
}
}
for (int i = start; i <= rightEnd; i++) {
A[i] = tmp[i - start];
}
}
}
return global;
}
}
遍历判断
class Solution {
public boolean isIdealPermutation(int[] A) {
for (int i = 0; i < A.length; i++) {
if (Math.abs(A[i] - i) > 1) return false;
}
return true;
}
}