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.
local inversion可以O(N)搞定,global inversion用merge sort可以O(N*logN)搞定,但是数据是0..N的permutation,那应该可以减到O(N),后面继续思考一下,发现并不需要求出global inversion的值,因为local inversion也是global inversion,只要没有多出来的inversion,2者就一样了,多出来的情况有2种
1. 连续descending的数的个数大于2
2. 前后2个连续descending的interval中,前面的interval的max比后面interval的min大,这样就可以另外构造出额外的inversion
然后发现这样即使不是0..N的permutation也是成立的
class Solution:
def isIdealPermutation(self, A):
"""
:type A: List[int]
:rtype: bool
"""
mi, ma, cnt, idx = [A[0]], [A[0]], [1], 0
for i in range(1, len(A)):
if A[i]<A[i-1]:
mi[idx] = min(mi[idx], A[i])
ma[idx] = max(ma[idx], A[i])
cnt[idx] += 1
else:
idx += 1
mi.append(A[i])
ma.append(A[i])
cnt.append(1)
for i in range(len(mi)):
if cnt[i]>2: return False
for i in range(len(mi)-1):
if ma[i]>mi[i+1]:
return False
return True
s=Solution()
print(s.isIdealPermutation([0,3,2,1]))
print(s.isIdealPermutation([2,1,0]))
print(s.isIdealPermutation([1,0,2]))
print(s.isIdealPermutation([1,2,0]))
如果再提炼一下,就是:交换local inversion后数组是不是有序的
Key insights:
- every local inversion is also a global inversion
- so "local inversions == global inversions" can be interpreted as "there are only local inversions"
- if there are only local inversions, the array will be sorted after making all local inversions
- if there are inversions that are not local, the array won't be sorted after making all local inversions
class Solution(object):
def isIdealPermutation(self, A):
"""
:type A: List[int]
:rtype: bool
"""
N=len(A)
for i in xrange(1, N):
if A[i-1]==A[i]+1:
A[i], A[i-1]=A[i-1], A[i]
elif A[i-1]!=i-1:
return False
return True
然后这里还限定了数组范围,还可以更加简单
class Solution {
public:
bool isIdealPermutation(vector<int>& A) {
for (int i = 0; i < A.size(); ++i) {
if (abs(A[i] - i) > 1) return false;
}
return true;
}
};