775. 全局倒置与局部倒置

数组 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 个局部倒置。

注意:

  • A 是 [0, 1, ..., A.length - 1] 的一种排列
  • A 的长度在 [1, 5000]之间
  • 这个问题的时间限制已经减少了。

 

第一反应是算出全局倒置和局部倒置的数量,然后比较,再返回结果就行了。局部倒置好计算,扫一遍数据就可以了。全局倒置要知道每个数后边有几个数比当前数大,直接暴力解决的话,复杂度是O(n^{2})。注意里边还提示时间限制减少了,直觉告诉我这个估计不行。

又想了一下,题目只要判断全局倒置和局部倒置数量是否一样,而局部倒置一定是全局倒置,因此,只要判断这个数组中是否有不是局部倒置的全局倒置就可以了。判断方法就是

A[i]\leq A[j] \ \ \ \ \forall j-1>i

改式恒成立,返回True,有一个不满足就返回False。代码如下

class Solution:
    def isIdealPermutation(self, A):
        """
        :type A: List[int]
        :rtype: bool
        """
        min_A=[]
        for i in range(len(A)):
            min_A.append(0)
        for i in range(len(A)):
            index=len(A)-1-i
            if(i==0):
                min_A[index]=A[index]
            else:
                min_A[index]=min(A[index],min_A[index+1])
            if(index>1):
                if(A[index-2]>min_A[index]):
                    return False
        return True

速度很慢,200ms.......打败了12%的提交.....

 

然后网上查了一下,参考了这篇博客https://www.cnblogs.com/grandyang/p/8983098.html 

原来是题目中有个条件没用到,数组 A 是 [0, 1, ..., N - 1] 的一种排列。到如果i出现在了i-1,-,i+1以外的位置,那么一定存在一个不是局部倒置的全局倒置,因此,代码更新如下

class Solution:
    def isIdealPermutation(self, A):
        """
        :type A: List[int]
        :rtype: bool
        """
        for i in range(len(A)):
            if((A[i]-i)*(A[i]-i)>1):
                return False

        return True

96ms,击败100%的提交了。哈哈

if((A[i]-i)*(A[i]-i)>1):

这个绝对值判断语句,用abs是最慢的,分正负分别判断是否小于-1和大于1和这一句速度差不多,但这一句稍微快一点。在这一题里快了4ms

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值