现在的位置: 首页 > 综合 > 正文

a very interesting Microsoft interview problem

2013年06月18日 ⁄ 综合 ⁄ 共 1684字 ⁄ 字号 评论关闭

Given an array of 0s and 1s, find out: 

1. all the
subarrays where number of 0s = number of 1s 

2. max length subarrays where number of 0s = number of 1s 


The array is not sorted and can be in any order. Can you do it in O(n) time?


The O(n^2) solution is easy to think of. use proprocessing and check every possible subarray.

But for the O(n) one, it's tricky. Here's one best solution

 
Loler has come up with.


Basically, use divide and conquer. if there's n subarrays that matches the requirement and you add 1 or 0 after that, how many you can get in total? That becomes straight forward. assume we keep the sum and add 1 if is 1, minus
1 if is 0.

eg. 1001, we have 3 subs that match the requirement, then 1001 1 has 4 subs. why? cause the sum becomes 1, and the it has appeared before only once. so it will be 3+1=4. 

if not clear see the codes below.


Below is his explanation:

Assuming by subsequence you actually meant _subarray_, an O(n) time (expected) algorithm is possible. 

Traverse the array from left to right, and maintain a running sum of number of ones - number of zeroes. 

You also have a hashtable keyed on the running sum, and which contains information regarding the number of times that running sum appears,
and also the leftmost index for which that sum appears. 


Using this structure, we can compute the answers for both 1 and 2. 

For instance, to compute the number, we check if the running sum appeared before. If it appeared k times before, then we get k new sub-arrays
with equal number of zeroes and ones. 


The max length uses the left most such idx. 
Here is quick code in python

def equal_count(lst):
	bits = [-1,1]
	counts = {}
	counts[0] = 1, -1
	run_sum = 0
	total_count = 0
	max_len = 0
	cur_idx = -1
	for bit in lst:
		cur_idx += 1
		run_sum += bits[bit]
		if run_sum in counts:
			c, idx = counts[run_sum]
			total_count += c
			if cur_idx - idx > max_len:
				max_len = cur_idx - idx
			counts[run_sum] = c+1, idx
		else:
			counts[run_sum] = 1, cur_idx
	return total_count, max_len	
    
def main():
	print equal_count([0,1,0,1,0,1])
   
if __name__ == "__main__":
	main()

抱歉!评论已关闭.