数组 A 是 [0, 1, …, N - 1] 的一种排列,N 是数组 A 的长度。全局倒置指的是 i,j 满足 0 <= i < j < N 并且 A[i] > A[j] ,局部倒置指的是 i 满足 0 <= i < N 并且 A[i] > A[i+1] 。
当数组 A 中全局倒置的数量等于局部倒置的数量时,返回 true 。
示例 1:
输入: A = [1,0,2]
输出: true
解释: 有 1 个全局倒置,和 1 个局部倒置。
示例 2:
输入: A = [1,2,0]
输出: false
解释: 有 2 个全局倒置,和 1 个局部倒置。
链接:https://leetcode.com/problems/global-and-local-inversions/
解题思路:
本题的直观思想是分别计算出全局倒置和局部倒置数,然后比较二者是否相等,这样计算全局倒置(即求数组的逆序对数)的复杂度会达到O(N²)。
仔细想来,全局和局部都是出现逆序,不同的是,局部是相邻元素之间,而全局是间距超过1的两个元素之间。而且,局部倒置一定包含在全局倒置中。想到这里,不能发现,我们只需要检查当i >= 2时, 是否会出现A[i - 2] > min(A[i: ])的情况。
我们可以从后往前遍历,同时记录下当前出现过的最小值,代替求min(A[i: ])的步骤。
我的代码:
class Solution(object):
def isIdealPermutation(self, A):
"""
:type A: List[int]
:rtype: bool
"""
# 从后往前遍历,保留最小值
l = len(A)
cur_min = l
for i in range(l - 1, 1, -1):
cur_min = min(A[i], cur_min)
if i >= 2 and A[i - 2] > cur_min:
return False
return True
官方的奇思妙想解法,为之惊叹!
class Solution(object):
def isIdealPermutation(self, A):
"""
:type A: List[int]
:rtype: bool
"""
# 优化
for i in range(len(A)):
if abs(A[i] - i) > 1:
return False
return True
Time: O(N)
Space: O(1)
难度: 中等