Skip to content

Commit

Permalink
interval sum
Browse files Browse the repository at this point in the history
  • Loading branch information
idf committed Jun 16, 2015
1 parent 3098d02 commit d82728c
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 5 deletions.
83 changes: 83 additions & 0 deletions Interval Sum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""
Given an integer array (index from 0 to n-1, where n is the size of this array), and an query list. Each query has two
integers [start, end]. For each query, calculate the sum number between index start and end in the given array, return
the result list.
Have you met this question in a real interview? Yes
Example
For array [1,2,7,8,5], and queries [(1,2),(0,4),(2,4)], return [9,23,20]
Note
We suggest you finish problem Segment Tree Build, Segment Tree Query and Segment Tree Modify first.
Challenge
O(logN) time for each query
"""
__author__ = 'Daniel'


class SumSegmentTreeNode(object):
def __init__(self, start, end, s):
self.start, self.end, self.s = start, end, s
self.left, self.right = None, None


class SumSegmentTree(object):
def __init__(self, A):
self.A = A
self.root = self.build_tree(0, len(self.A))

def build_tree(self, s, e):
"""
segment: [s, e)
"""
if s >= e:
return None

if s+1 == e:
return SumSegmentTreeNode(s, e, self.A[s])

left = self.build_tree(s, (s+e)/2)
right = self.build_tree((s+e)/2, e)
sm = 0
if left: sm += left.s
if right: sm += right.s
root = SumSegmentTreeNode(s, e, sm)
root.left = left
root.right = right

return root

def query(self, root, s, e):
if not root:
return 0

if s <= root.start and e >= root.end:
return root.s

if s >= root.end or e <= root.start:
return 0

l = self.query(root.left, s, e)
r = self.query(root.right, s, e)
return l+r


class Solution:
def intervalSum(self, A, queries):
"""
Interval Tree
Alternative method: dp
:param A: integer array
:param queries: The ith query is [queries[i-1].start, queries[i-1].end]
:return: The result list
"""
ret = []
tree = SumSegmentTree(A)
for q in queries:
ret.append(tree.query(tree.root, q.start, q.end+1))

return ret


4 changes: 2 additions & 2 deletions Segment Tree Modify.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ def modify(self, root, index, value):
"""
if root is None:
return
if index<root.start or index>root.end:
if index < root.start or index > root.end:
return
if root.start==index and root.end==index:
if root.start == index and root.end == index:
root.max = value
return

Expand Down
7 changes: 4 additions & 3 deletions Segment Tree Query.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
the given root of segment tree.
"""
__author__ = 'Danyang'
import sys


class SegmentTreeNode:
Expand All @@ -21,10 +22,10 @@ def query(self, root, start, end):
:param root, start, end: The root of segment tree and an segment / interval
:return: The maximum number in the interval [start, end]
"""
import sys
if start<=root.start and end>=root.end:

if start <= root.start and end >= root.end: # the start and end remain unchanged during the query.
return root.max
if start>end:
if start > end:
return -sys.maxint-1

maxa = -sys.maxint-1
Expand Down

0 comments on commit d82728c

Please sign in to comment.