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