Sliding Window Median

Source: Internet
Author: User

Given an array of n integers with duplicate number, and a moving window (size k), move the window at each iteration from the Start of the array, find the maximum number inside the window at each moving.

Has you met this question in a real interview?Yes Example

For array [1, 2, 7, 7, 8] , moving window size k = 3 . return[7, 7, 8]

At first the window was at the start of the An array like this

[|1, 2, 7| ,7, 8], return the maximum 7 ;

Then the window move one step forward.

[1, |2, 7 ,7|, 8], return the maximum 7 ;

Then the window move one step forward again.

[1, 2, |7, 7, 8|], return the maximum 8 ;

It is also a question of sliding window. Finding the median, very similar to the find Median from Data stream, can be thought of as a good idea to solve with minheap and maxheap.

However, unlike data flow, sliding window has to be removed, so it is better to use Hashheap.

The specific solution is to break the movement of each window into an increment element and delete the element one at a time. Because there are two of heaps, it is critical to decide which heap to delete. Because test instructions, my practice is that maxheap always store and minheap the same number or more than 1 of the number, so that the median is always the maxheap heap top, each time you can delete the element and the median to compare, large in the minheap, small or equal in Maxheap deleted. The actual solution in the Lintcode timeout, but if more than hashheap write an interface function, contain (now), using the hash table to check, this practice successfully passed, the code is as follows:

classSolution:"""@param nums:a List of integers.    @return: The median of element inside the window at each moving. """    defMedianslidingwindow (self, nums, K):ifLen (nums) < Kor  notNums:return[] Minheap= Hashheap ('min') Maxheap= Hashheap ('Max')         forIinchxrange (k):ifI% 2: Maxheap.add (Nums[i]) Minheap.add (Maxheap.pop ())Else: Minheap.add (Nums[i]) Maxheap.add (Minheap.pop ()) median= []         forIinchxrange (k, Len (nums)): Median.append (Maxheap.top ())ifMinheap.contain (Nums[i-K]): Minheap.delete (Nums[i-K]) Maxheap.add (Nums[i]) Minheap.add (Maxheap.pop () )Else: Maxheap.delete (nums[i-K]) Minheap.add (Nums[i]) Maxheap.add (Minheap.pop ()) Median.append (Maxheap.top ()) returnMedianclassNode (object):"""the type of class stored in the HashMap, in case there is many same heights in the heap, maintain the number """    def __init__(self, id, num): Self.id= ID#ID means its ID in heap arraySelf.num = num#Number of same value in the This ID        classHashheap (object):def __init__(self, mode): Self.heap=[] Self.mode=mode self.size=0 Self.hash= {}    defTop (self):returnSELF.HEAP[0]ifLen (self.heap) > 0Else0defcontain (self, now):ifSelf.hash.get (now):returnTrueElse:            returnFalsedefIsEmpty (self):returnLen (self.heap) = =0def_comparesmall (self, A, b):#compare function in different mode        ifA <=B:ifSelf.mode = ='min':                returnTrueElse:                returnFalseElse:            ifSelf.mode = ='min':                returnFalseElse:                returnTruedef_swap (self, IdA, IdB):#swap the values in the heap, we also need to the changeValA =Self.heap[ida] Valb=Self.heap[idb] NumA=Self.hash[vala].num NumB=Self.hash[valb].num Self.hash[valb]=Node (IdA, NumB) Self.hash[vala]=Node (IdB, NumA) Self.heap[ida], Self.heap[idb]=Self.heap[idb], Self.heap[ida]defAdd (self, now):#the key, height in this placeSelf.size + = 1ifSelf.hash.get (now): Hashnow=Self.hash[now] Self.hash[now]= Node (hashnow.id, Hashnow.num + 1)        Else: Self.heap.append (now) Self.hash[now]= Node (len (self.heap)-) Self._siftup (len (self.heap)-1)                defPop (self):#pop the top of the heapSelf.size-= 1 Now=Self.heap[0] Hashnow=Self.hash[now] Num=Hashnow.numifnum = = 1: Self._swap (0, Len (self.heap)-1) Self.hash.pop (now) Self.heap.pop () self._siftdown (0)Else: Self.hash[now]= Node (0, Num-1)        return NowdefDelete (self, now): Self.size-= 1Hashnow=Self.hash[now] ID=hashnow.id Num=Hashnow.numifnum = = 1: Self._swap (ID, len (self.heap)-1)#Like the common delete operationSelf.hash.pop (now) Self.heap.pop ()ifLen (self.heap) >id:self._siftup (ID) self._siftdown (ID)Else: Self.hash[now]= Node (ID, num-1)                defparent (self, id):ifid = =0:return-1return(id-1)/2def_siftup (self,id): whileABS (ID-1)/2 < ID:#Iterative versionParentID = (id-1)/2ifSelf._comparesmall (Self.heap[parentid],self.heap[id]): Break            Else: Self._swap (ID, parentid) ID=ParentIDdef_siftdown (self, id):#Iterative version         while2*id + 1 <Len (self.heap): l= 2*id + 1R= L + 1Small=IDifSelf._comparesmall (Self.heap[l], Self.heap[id]): Small=LifR < Len (self.heap) andSelf._comparesmall (Self.heap[r], Self.heap[small]): Small=RifSmall! =Id:self._swap (ID, small)Else:                 BreakID= Small

The time complexity of the above practice is O (NLOGK). But this problem requires a median, and there is no particularly good way to find the solution of O (n) like sliding Window maximum. Just the sauce.

Sliding Window Median

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.