Search code examples
javamathlookupinteger-hashing

How to look up range from set of contiguous ranges for given number


so simply put, this is what I am trying to do:

I have a collection of Range objects that are contiguous (non overlapping, with no gaps between them), each containing a start and end int, and a reference to another object obj. These ranges are not of a fixed size (the first could be 1-49, the second 50-221, etc.). This collection could grow to be quite large.

I am hoping to find a way to look up the range (or more specifically, the object that it references) that includes a given number without having to iterate over the entire collection checking each range to see if it includes the number. These lookups will be performed frequently, so speed/performance is key.

Does anyone know of an algorithm/equation that might help me out here? I am writing in Java. I can provide more details if needed, but I figured I would try to keep it simple.

Thanks.


Solution

  • If sounds like you want to use a TreeMap, where the key is the bottom of the range, and the value is the Range object.

    Then to identify the correct range, just use the floorEntry() method to very quickly get the closest (lesser or equal) Range, which should contain the key, like so:

        TreeMap<Integer, Range> map = new TreeMap<>();
        map.put(1, new Range(1, 10));
        map.put(11, new Range(11, 30));
        map.put(31, new Range(31, 100));
    
        // int key = 0; // null
        // int key = 1; // Range [start=1, end=10]
        // int key = 11; // Range [start=11, end=30]
        // int key = 21; // Range [start=11, end=30]
        // int key = 31; // Range [start=31, end=100]
        // int key = 41; // Range [start=31, end=100]
        int key = 101; // Range [start=31, end=100]
        // etc.
    
        Range r = null;
        Map.Entry<Integer, Range> m = map.floorEntry(key);
        if (m != null) {
            r = m.getValue();
        }
        System.out.println(r);
    

    Since the tree is always sorted by the natural ordering of the bottom range boundary, all your searches will be at worst O(log(n)).

    You'll want to add some sanity checking for when your key is completely out of bounds (for instance, when they key is beyond the end of the map, it returns the last Range in the map), but this should give you an idea how to proceed.