Leetcode: 493. Reverse Pairs

Description

Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].
You need to return the number of important reverse pairs in the given array.

Example

Input: [1,3,2,3,1]
Output: 2

Note

The length of the given array will not exceed 50,000.
All the numbers in the input array are in the range of 32-bit integer.

分析

如果是 C++, 就需要写 segment tree 或者 树状数组了。 然而在 python 中只好用 屌丝版的方法了,结果却超时。后面将结合代码分析超时的原因

code

  • AC
class Solution(object):
    def reversePairs(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums)<2:
            return 0
        pre = []
        res = 0
        for i in range(len(nums)):
            if not pre:
                pre.append(nums[i])
            else:
                index = bisect.bisect_right(pre,2*nums[i])  # 因为输入数字的特点,用 binary search 最多只需要查找 20 次(如果没有重复数字的话)
                if index < len(pre):
                    res += len(pre) - index
                bisect.insort(pre,nums[i])
        return res
  • TLE
class Solution(object):
    def reversePairs(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        dp = [[] for _ in range(33)]
        ndp = [[] for _ in range(33)]
        zerocount = 0
        N = len(nums)
        count = 0
        for i in range(N-1, -1, -1):
            bitN = len('{0:b}'.format(nums[i]))
            vv = nums[i]
            if vv > 0:
                bisect.insort_right(dp[bitN+1], vv)  
                for j in range(bitN):  # 这里要 bitN 次
                    count += len(dp[j])
                for v in dp[bitN]:   # 这里可能要 many times
                    if vv > 2*v:
                        count += 1
                    else:
                        break
                for j in range(33):  # 这里要 33 次
                    count += len(ndp[j])
                count += zerocount
            elif vv == 0:
                for j in range(33):  
                    count += len(ndp[j])
                zerocount += 1
            else:
                for j in range(bitN, 33):
                    count += len(ndp[j])
                for v in dp[bitN-1]:
                    if vv > 2 * v:
                        count += 1
                bisect.insort_left(ndp[bitN], vv)
        return count
写的这么复杂,还不如用 bisect ~~

总结

画蛇添足
原文地址:https://www.cnblogs.com/tmortred/p/13340536.html