find minimum-length subarray that has all numbers

自古美人都是妖i 提交于 2019-12-03 15:39:21

Your algorithm is good but ignoring the time that len(trees) < K, it's O(NK) because every call to min and max is O(K). There's no need to call max because max(trees.values()) == i. Dealing with min is trickier, but if you keep track of which key corresponds to the minimum index then you can recalculate it only when that key is updated.

A minor point is that your last if doesn't always need to be checked.

Overall:

trees = {}
min_idx = (1, N)
min_length = N
first_index = -1
for i in range(N):
    trees[alley[i]] = i
    if len(trees) == K:
        if first_index == -1 or alley[first_index] == alley[i]:
            first_index = min(trees.values())
        idx = (first_index+1, i+1)
        length = idx[1] - idx[0] + 1
        if length < min_length:
            min_idx = idx
            min_length = length
            if min_length == K:
                break

Make integer array Counts[K], fill with zeros.
Keep some variables - left index L, right index R (like your idx[0] and idx[1]), zero count Z.
Set L and R to 1, increment Counts[A[1]], set Z to K-1

Move R, incrementing Counts[A[1]], and decrement Z if zero entry is updated, until Z becomes 0
At this moment subarray [L..R] contains all values from to K

Now move L, decrementing Counts entry for values leaving the window. Increment Z if some entry becomes 0. When Z becomes non-zero, stop moving L and move R again.

When R reaches N and L stops, process is over. Minimum length is minimum from valid (R-L+1) pairs

Example run for your [1 2 1 3 2]

Move R
1 0 0  Z=2
1 1 0  Z=1
2 1 0  Z=1
2 1 1  Z=0
Move L
1 1 1  Z=0
1 0 1  Z=1 Stop moving L, check previous L,R pair 2,4
Move R
1 1 1  Z=0
move L
9 1 1  Z=1 Stop moving L, check previous L,R pair 3,5
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!