List 如何编写这个返回列表中x和y之间的计数的算法?

List 如何编写这个返回列表中x和y之间的计数的算法?,list,algorithm,dictionary,pseudocode,List,Algorithm,Dictionary,Pseudocode,我遇到了这个算法问题,需要找到一种方法来返回一个列表S和另一个列表L中的计数,该列表在某个变量x和某个变量y(包括)之间,在O(1)时间内运行: 我对杰克提出了挑战。他将提交一份他最喜欢的年份列表(从0年到2020年)。如果杰克真的喜欢一年, 他可能会多次列出它。因为杰克在飞行中提出了这个清单,所以它是不存在的 特定顺序。具体而言,列表未排序,列表中出现的年份也未排序 多次出现在列表中的相邻位置 我还将提交这样一份年份清单 然后我会让Jack在0到2020之间随机选择一年。假设杰克选择了x年 同

我遇到了这个算法问题,需要找到一种方法来返回一个列表S和另一个列表L中的计数,该列表在某个变量x和某个变量y(包括)之间,在O(1)时间内运行:

我对杰克提出了挑战。他将提交一份他最喜欢的年份列表(从0年到2020年)。如果杰克真的喜欢一年, 他可能会多次列出它。因为杰克在飞行中提出了这个清单,所以它是不存在的 特定顺序。具体而言,列表未排序,列表中出现的年份也未排序 多次出现在列表中的相邻位置

我还将提交这样一份年份清单

然后我会让Jack在0到2020之间随机选择一年。假设杰克选择了x年

同时,我还将随机选取一个介于0和2020之间的年份。我想 选择y年。在不丧失一般性的情况下,假设x≤ y

一旦选择了x和y,我和杰克的时间就很短(可能是5分钟) 秒)来决定是否要重新执行选择x和y的过程

如果没有人要求重做,那么我们计算杰克列表中被重做的条目的数量 x和y之间(包括x和y),以及我的列表中x和y之间的条目数 包括在内

更严格地说,情况是这样的。给出了m和n个整数的列表S和L, 分别在[0,k]范围内,表示Jack和 I.您可以在O(m+n+k)时间内预处理S和L。然后必须给出一个算法 这将在O(1)时间内运行,这样我就可以决定是否需要重新执行,从而解决问题 以下问题:

输入:两个整数,x作为[0,k]的成员,y作为[0,k]的成员

输出:范围[x,y]内S中的条目数,以及[x,y]内L中的条目数

例如,假设S={3,1,9,2,2,3,4}。给定x=2和y=3,返回的计数 4岁


我更喜欢伪代码;这有助于我更容易地理解这个问题。

实现user3386109处理x=0的边情况的方法


用户3386109:制作直方图,然后计算直方图中每个条目的累计总和。假设S={3,1,9,2,2,3,4},k为9。直方图为H={0,1,2,2,1,0,0,0,0,1}。累积后,H={0,1,3,5,6,6,6,6,7}。给定x=2和y=3,计数为H[y]-H[x-1]=H[3]-H[1]=5-1=4。当然,x=0是一个必须处理的极端情况

# INPUT

S = [3, 1, 9, 2, 2, 3, 4]
L = [2, 9, 4, 6, 8, 5, 3]
k = 9

x = 2
y = 3

# Histogram for S
S_hist = [0]*(k+1)

for element in S:
    S_hist[element] = S_hist[element] + 1

# Storing prefix sum in S_hist 
sum = S_hist[0]
for index in range(1,k+1):
    sum = sum + S_hist[index]
    S_hist[index] = sum


# Similar approach for L

# Histogram for L
L_hist = [0] * (k+1)

for element in L:
    L_hist[element] = L_hist[element] + 1
    
# Stroing prefix sum in L_hist
sum = L_hist[0]
for index in range(1,k+1):
    sum = sum + L_hist[index]
    L_hist[index] = sum
    
# Finding number of elements between x and y (inclusive) in S
print("number of elements between x and y (inclusive) in S:")
if(x == 0):
    print(S_hist[y])
else:
    print(S_hist[y] - S_hist[x-1])
    
# Finding number of elements between x and y (inclusive) in S
print("number of elements between x and y (inclusive) in L:")
if(x == 0):
    print(L_hist[y])
else:
    print(L_hist[y] - L_hist[x-1])    

制作柱状图,然后计算柱状图中每个条目的累计和。假设
S={3,1,9,2,2,3,4}
k
为9。直方图是
H={0,1,2,2,1,0,0,0,0,1}
。累积后,
H={0,1,3,5,6,6,6,6,7}
。给定x=2和y=3,计数为
H[y]-H[x-1]=H[3]-H[1]=5-1=4
。当然,x=0是一个必须处理的极端情况。@user3386109如果在预处理之前不知道k,算法将如何更改?如果没有给定
k
,则可以对两个输入数组执行O(m+n)扫描,找到最大值,并调用
k
。您找到的
k
可能小于实际的
k
,但这不是问题。该算法需要
k
来正确调整直方图的大小。当然,如果
x
y
或两者都大于计算出的
k
,那么这是另一个需要处理的极端情况。@user3386109那么,有什么证据可以证明这个算法不会只输出一个看起来不像实际条目的数字呢?我认为
s_hist[element]=s_hist[element]+1
将打印以下内容:
[2,2,2,2,2,2,2,2…]
@JohnAdams不,这是一种数组索引方法(散列),元素从0到k,索引(键)作为元素,其值为该元素出现的次数。对,但行
S_hist=[0]*(k+1)
似乎正在使for循环的条件成为
shist[element]=S_hist[element]+1
影响列表中的每个元素,而不是它的意图,即只影响索引
元素
。ope,没关系,你是对的。我正在使用
S_hist=[[0,0]]*(k+1)
查看是否可以将S和L组合成一个直方图,但它似乎不起作用。@JohnAdams不使用此命令:S_hist=[[0,0]]*(k+1)使用循环添加[0,0]->k+1次。