I crafted a very straightforward solution using a HashSet
. Since contains
and remove
are O(1) operations, you can simply create a new interval from a random set item and 'expand' the interval it until you discover its full size, removing items from the set as you go along. The removal is key, because this is what prevents you from 'repeating' any intervals.
It might help to think about it this way - the list has K intervals, whose sizes add up to N. Your task, then, is to discover what these intervals are, without repeating any intervals or items. This is why the HashSet is perfect for the job - you can efficiently remove items from the set as you expand your intervals. Then all you need to do is keep track of the largest interval as you go along.
- Put the list into a
HashSet
- While the set is non-empty:
- remove an item at random from the set
- Define a new interval from that item
- Expand the interval as follows:
- Define
i = interval.start-1
- While the set contains
i
, remove i
from the set and decrement both i
and interval.start
- Repeat step 2 in the other direction (expand up from
interval.end
)
- If the expanded interval is larger than the previously largest interval, record the new interval as the largest interval
- Return the largest interval
Here is the solution in Java:
public class BiggestInterval {
static class Interval {
int start;
int end;
public Interval(int base) {
this(base,base);
}
public Interval(int start, int end) {
this.start = start;
this.end = end;
}
public int size() {
return 1 + end - start;
}
@Override
public String toString() {
return "[" + start + "," + end + "]";
}
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(biggestInterval(Arrays.asList(1,3,5,7,4,6,10)));
}
public static Interval biggestInterval(List list) {
HashSet set = new HashSet(list);
Interval largest = null;
while(set.size() > 0) {
Integer item = set.iterator().next();
set.remove(item);
Interval interval = new Interval(item);
while(set.remove(interval.start-1)) {
interval.start--;
}
while(set.remove(interval.end+1)) {
interval.end++;
}
if (largest == null || interval.size() > largest.size()) {
largest = interval;
}
}
return largest;
}
}