简体   繁体   中英

Java data structure for finding and using objects that have attribute at least X

I'm looking for a data structure (preferably using a Java built-in collection class) that allows me to efficiently search for all objects that have a data attribute of greater than X. It will be part of an assignment system.

For example, suppose I have several public transportation buses and their capacities:

Bus 1: capacity 20
Bus 2: capacity 12
Bus 3: capacity 24

Now, I would like to make the following assignments:

Group 1: 16 passengers
Group 2: 19 passengers

Group 1 should efficiently find bus 1 or bus 3 and assign the group to (say) bus 1.

Group 2 should efficiently find bus 1 or bus 3, find that bus 1 is occupied, and assign the group to bus 3.

What kind of data structures are needed here?

To find the matching buses that meet needed capacity, I can binary search in O(lg N) time to find the minimum capacity matching my required number of passengers and then scan O(N) time to find all higher-capacity buses with at least that number.

Then how can I choose among matching buses to make the final assignment (for example, when group 2 needs to choose between bus 1, which is already occupied, and bus3)?

I think you can achieve using O(lg N)+O(N) ..

First I would add a flag to the bus type for marking that it's occupied. If this resulting collection is sorted on capacity then you can reach bus with minimum capacity(say X) greater than your group in O(lg N).

You can then traverse the collection from X till the max value in O(N) until you find the first unoccupied bus.

Based on your specs, I would suggest something as such.

@lombok.Data
@AllArgsConstructor
public class Group {
   private Integer id;
   private Integer size;
}

@lombok.Data
@AllArgsConstructor
public class Bus {
   private Integer id;
   private Integer capacity;
   private Boolean occupied;
}

I believe that you could get this to O(N) utilizing the Stream API filter, without the O(lg N) of first sorting. Assuming that you have a collection of buses, a method to find the available bus in O(N) would look something like this

public Optional<Bus> getAvailableBus (Group group) {
    return buses.stream().filter(
            bus -> bus.getCapacity() >= group.getSize() && !bus.isOccupied()).findFirst();
}

I would use a balanced binary search tree. "Ceil" helps finding the right bus. "Ceil" is a O(log N) operation. After finding this bus, delete it from the tree. Since it's a balanced binary tree, again delete is a O(log N) operation. Complete implementation of left leaning red black tree that does these operations in log N complexity can be found here: http://algs4.cs.princeton.edu/33balanced/RedBlackBST.java.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM