Example:
Day 1 - 5 => 10%
Day 2 - 8 => 5%
Day 4 - 6 => 20%
Interval with max discount:
Day 4 - 5 => 35%
interval:
start, end
discount
// time: O(nlogn)
getmaxdiscount(intervals):
times = split(intervals) // O(nlogn)
maxdiscount = getmaxdiscount(times) // O(n)
return maxdiscount
time:
value
discount
isstart
// split interval into time
// time: O(nlogn)
split(intervals):
times = new
foreach interval in intervals:
times.add(new time(interval.start, interval.discount, true))
times.add(new time(interval.end, interval.discount, false))
// when value is same, the start time should come first
return times.orderby(value, !isstart)
// time: O(n)
getmaxdiscount(times):
discount = 0
start, end = null, maxdiscount = 0
foreach time in times:
if time.isstart: // time is start
discount += time.discount
if discount > maxdiscount:
maxdiscount = discount
start = time.value
end = null
else: // time is end
if discount == maxdiscount:
end = time.value
discount -= time.discount
return { start, end, maxdiscount }
--example:
Day 1 + 10%, 10%, {Days 1-?, 10%}
Day 2 + 5%, 15%, {Days 2-?, 15%}
Day 4 + 20%, 35%, {Days 4-?, 35%}
Day 5 - 10%, 25%, {Days 4-5, 35%} --max
Day 6 - 20%, 5%,
Day 8 - 5%, 0%,
There could multiple intervals with same max discount so capture the longer interval.
// time: O(n)
getmaxdiscount(times):
discount = 0
start, end = null, maxdiscount = 0
max = null
foreach time in times:
if time.isstart: // time is start
discount += time.discount
if discount >= maxdiscount: // = to capture longer interval
maxdiscount = discount
start = time.value
end = null
else: // time is end
if discount == maxdiscount:
end = time.value
curr = new interval(start, end, maxdiscount)
if max == null || curr > max: //operator > overloaded
max = curr
discount -= time.discount
return max
interval: icomparable
// compare discount first, length of interval second
compare(other):
c = discount.compare(other.discount)
if c == 0:
c = (end - start).compare(other.end - other.start)
return c
No comments:
Post a Comment