假设你正在读取一串整数。每隔一段时间,你希望能找出数字 x 的秩(小于或等于 x 的值的个数)。请实现数据结构和算法来支持这些操作,也就是说:

实现 track(int x) 方法,每读入一个数字都会调用该方法;
实现 getRankOfNumber(int x) 方法,返回小于或等于 x 的值的个数。

注意:本题相对原题稍作改动

示例:

输入:
["StreamRank", "getRankOfNumber", "track", "getRankOfNumber"]
[[], [1], [0], [0]]
输出:
[null,0,null,1]

提示:

  • x <= 50000
  • track 和 getRankOfNumber 方法的调用次数均不超过 2000 次

Python 解答:
1.线性搜索

class StreamRank:

    def __init__(self):
        self.arr = []

    def track(self, x: int) -> None:
        if not self.arr:
            self.arr.append([x, 1])
        else:
            i = 0
            while i < len(self.arr):
                if self.arr[i][0] < x:
                    i += 1
                elif self.arr[i][0] == x:
                    for j in range(i, len(self.arr)):
                        self.arr[j][1] += 1
                    break
                elif self.arr[i][0] > x:
                    if i == 0:
                        self.arr.insert(i, [x, 1])
                    elif i > 0:
                        self.arr.insert(i, [x, self.arr[i-1][1]+1])
                    for j in range(i+1, len(self.arr)):
                        self.arr[j][1] += 1
                    break
            if i == len(self.arr):
                self.arr.append([x, self.arr[i-1][1]+1])

    def getRankOfNumber(self, x: int) -> int:
        i = 0
        while i < len(self.arr) and self.arr[i][0] <= x:
            i += 1
        if i - 1 < 0:
            return 0
        else:
            return self.arr[i-1][1]

# Your StreamRank object will be instantiated and called as such:
# obj = StreamRank()
# obj.track(x)
# param_2 = obj.getRankOfNumber(x)

2.树状数组

class StreamRank:

    def __init__(self):
        self.arr = [0 for i in range(50002)]

    def track(self, x: int) -> None:
        i = x+1
        while i < len(self.arr):
            self.arr[i] += 1
            i += i & (-i)

    def getRankOfNumber(self, x: int) -> int:
        total = 0
        i = x+1
        while i > 0:
            total += self.arr[i]
            i -= i & (-i)
        return total

# Your StreamRank object will be instantiated and called as such:
# obj = StreamRank()
# obj.track(x)
# param_2 = obj.getRankOfNumber(x)
最后修改日期: 2021年5月7日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。