8.23 - hard - 95

2017-08-24  本文已影响0人  健时总向乱中忙

493. Reverse Pairs

值得一看的post https://discuss.leetcode.com/topic/79227/general-principles-behind-problems-similar-to-reverse-pairs
用bst来解决,不过会TLE,因为bst可能不是balanced
用segment tree来解决, 不知道为何用segment tree还是TLE

用mergesort的想法来做
class Solution(object):
    def mergeAndCount(self, A, l, r):
        if l >= r:
            return 0
        
        m = (l+r) / 2
        c = 0
        c += self.mergeAndCount(A, l, m)                    
        c += self.mergeAndCount(A, m+1, r)                    
        x = A[l:m+1]
        y = A[m+1:r+1]
        n1, n2 = len(x), len(y)
        j = 0
        for i in xrange(n1):
            while j < n2 and x[i] > 2*y[j]:
                j += 1
            c += j
        A[l:r+1] = sorted(A[l:r+1])
        return c
        
    def reversePairs(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # self.count = 0
        n = len(nums)
        if n < 2:
            return 0
        return self.mergeAndCount(nums, 0, n-1)
TLE
class Solution(object):
    def reversePairs(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # 依次把元素加入binary search tree
        # 对于新进来的元素搜索比其小的值
        if not nums or len(nums) < 2:
            return 0
        s = set(nums)
        s = sorted(list(s))
        index_map = {}
        for i, num in enumerate(s):
            index_map[num] = i
        root = self.buildTree(0, len(s) - 1);

        result = 0
        for i in range(len(nums)):
            num = nums[i] * 2 + 1
            index = bisect.bisect_left(s, num)
            result += self.getCount(index, len(s) - 1, root)
            self.update(index_map.get(nums[i]), root)
        return result

    def buildTree(self, l, r):
        if l == r:
            return SegmentNode(l, r)
        cur = SegmentNode(l, r)
        mid = (r + l) / 2
        cur.lc = self.buildTree(l, mid)
        cur.rc = self.buildTree(mid + 1, r)
        return cur

    def getCount(self, l, r, node):
        if not node or node.l > r or node.r < l:
            return 0
        if l == node.l and r == node.r:
            return node.count
        mid = (node.r + node.l) / 2
        if mid >= r:
            return self.getCount(l, r, node.lc)
        elif mid < l:
            return self.getCount(l, r, node.rc)
        else:
            return self.getCount(l, mid, node.lc) + self.getCount(mid + 1, r, node.rc)

    def update(self, idx, node):
        if node.l <= idx and node.r >= idx:
            node.count += 1
        else:
            return
        if node.l == node.r:
            return
        self.update(idx, node.lc)
        self.update(idx, node.rc)

class SegmentNode(object):
    def __init__(self, l, r):
        self.l = l
        self.r = r
        self.rc = None
        self.lc = None
        self.count = 0
上一篇下一篇

猜你喜欢

热点阅读