重複するセッションをマージします。セッションの終了値を見つけるにはどうすればよいですか?[カープーリングに似たリートコード]

coderWorld

重複するセッションの数を計算する次のコードブロックがあります。異なる間隔が与えられた場合、タスクは、これらの間隔間のオーバーラップの最大数をいつでも出力し、オーバーラップした間隔を見つけることです。

def overlap(v): 

    # variable to store the maximum 
    # count 
    ans = 0
    count = 0
    data = [] 

    # storing the x and y 
    # coordinates in data vector 
    for i in range(len(v)): 

        # pushing the x coordinate 
        data.append([v[i][0], 'x']) 

        # pushing the y coordinate 
        data.append([v[i][1], 'y']) 

    # sorting of ranges 
    data = sorted(data) 

    # Traverse the data vector to 
    # count number of overlaps 
    for i in range(len(data)): 

        # if x occur it means a new range 
        # is added so we increase count 
        if (data[i][1] == 'x'): 
            count += 1

        # if y occur it means a range 
        # is ended so we decrease count 
        if (data[i][1] == 'y'): 
            count -= 1

        # updating the value of ans 
        # after every traversal 
        ans = max(ans, count) 

    # printing the maximum value 
    print(ans) 

# Driver code 
v = [[ 1, 2 ], [ 2, 4 ], [ 3, 6 ],[3,8]] 
overlap(v) 

これはを返します3しかし、既存のアプローチを変更して最大重複間隔を返すための最良の方法は何でしょうか?この場合、どちらである必要があります[3,4]

アランT。

(コレクションからの)counterオブジェクトを使用して、交差するサブ間隔のリストを作成し、それらと交差する元の間隔の数を数えることができます。リスト内の各間隔は、カウントを累積するために、これまでに見つかったすべてのサブ間隔と交差します。

v = [[ 1, 2 ], [ 2, 4 ], [ 3, 6 ],[3,8]] 

from collections import Counter
overCounts = Counter()
for vStart,vEnd in v:
    overlaps = [(max(s,vStart),min(e,vEnd)) for s,e in overCounts 
                if s<=vEnd and e>=vStart]
    overCounts += Counter(overlaps + [(vStart,vEnd)])

interval,count = overCounts.most_common(1)[0]
print(interval,count) # (3,4) 3

オーバーラップリストは、これまでに見つかったサブインターバルとの交差を検出します。s<=vEnd and e>=vStart間隔(s、e)が間隔(vStart、vEnd)と交差すると、Trueを返します。交差する間隔については、交差の開始と終了(サブ間隔)が必要です。交差点は最大の始点で始まり、最小の終点で終わります。したがって、開始位置のmax()と終了位置のmin()を使用して、サブインターバルを形成します。(max(s,vStart),min(e,vEnd))

vStart               vEnd
[--------------------]
       [--------------------------]
       s                          e

       [-------------]
--max->               <----min-----

[編集]正直なところ、私はあなたのオリジナルのアプローチが私のものよりも好きです。O(NLogN)時間で応答しますが、データによってはO(N ^ 2)まで上がる可能性があります。

元のアプローチの結果に対応するサブインターバルをキャプチャするには、最後に検出された開始位置を追跡する変数を追加し、「y」条件内でより高いカウントの検出を移動する必要があります。

例えば:

 lastStart = maxStart = maxEnd = None

 # ...

    if (data[i][1] == 'x'): 
        lastStart = data[i][0]     # last start of sub-interval 
        count += 1

    if (data[i][1] == 'y'): 
        if count > ans:            # detect a greater overlap
           maxStart = lastStart    # start of corresponding sub-interval
           maxEnd   = data[i][0]
           ans      = count 
        count -= 1

    # ans = max(ans, count)  <-- removed

# ...   

また、accumulateを使用して実装することもできます。

v = [[ 1, 2 ], [ 2, 4 ], [ 3, 6 ],[3,8]]

from itertools import accumulate
edges           = sorted((p,e) for i in v for p,e in zip(i,(-1,1)))
counts          = accumulate(-e for _,e in edges)
starts          = accumulate((p*(e<0) for p,e in edges),max)
count,start,end = max((c+1,s,p) for c,s,(p,e) in zip(counts,starts,edges) if e>0)

print(count,[start,end]) # 3 [3, 4]

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ