简体   繁体   中英

Which data structure to use for the following class

I have both of these classes given (below in the code blocks) and I have to implement the given methods of TTEvent in no longer then O(log(N). I am allowed to use the following data structures:

  • Integer[] - Array of start points or durations
  • List, queue, dequeue or set - of start points or durations
  • Map - mapping of start point to end point or duration
  • Map - mapping of start point to time interval
  • TTinterval[] - Array of time interval
  • List, queue, dequeue or set - of time interval

There where also some mapping of duration to xyz, but since duration is not unique I excluded those immediately.

I am allowed to use subtypes like linked list, array list, hashmap etc.

I can't seem to find a fitting data structure to use. I mostly get stuck up on the methods that get passed a duration. All the ways I can think of finding data in those structures would be slower then O(log(N), mainly O(N), since I would either loop or call .contain(value) on a map.

It is to assume that N will be large rather then small.

Now ofc I don't want a solution, but some pointers as to what would be the most desired structure to use and maybe some tips specifically regarding the methods which pass a duration.

Java compiler has to be 1.8 if that makes any difference (jre/jdk 1.8)

    package tp;

    /**
    * Non changeable time-interval. start and end time-points are considered inclusive.
    */
    public class TTInterval {

      private final int start;

      private final int end;

      private final int duration;

      /**
       * Constructor.
       * 
       * @param start startpoint
       * @param end endpoint
       */
      public TTInterval(int start, int end) {
          this.start = start;
          this.end = end;
          this.duration = end - start + 1; // end inklusive
      }

      /**
       * @return startpoint
       */
      public int getStart() {
          return start;
      }

      /**
       * @return endpoint
       */
      public int getEnd() {
          return end;
      }

      /**
       * @return length
       */
      public int getDuration() {
          return duration;
      }

      @Override
      public String toString() {
          return "[(" + start + "-" + end + ")," + "{" + duration + "}]";
      }

      @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + end;
          result = prime * result + start;
          return result;
      }

      @Override
      public boolean equals(Object obj) {
          if (this == obj) {
              return true;
          }
          if (obj == null) {
              return false;
          }
          if (getClass() != obj.getClass()) {
              return false;
          }
          TTInterval other = (TTInterval) obj;
          if (end != other.end) {
              return false;
          }
          if (start != other.start) {
              return false;
          }
          return true;
      }

    }


import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * An event consists of a unchangeable name and a collection of time intervals to which it happens.
 * 
 * It delivers information regarding its assigned time intervals.
 * 
 */
public class TTEvent {

    private final String title; 
    private final LinkedHashMap<Integer, TTInterval> intervals; //not sure if this is a good way



    /**
     * constructor.
     * 
     * @param title - name of the event
     */
    TTEvent(String title, String[] attributes) {
        this.title = title;
        this.intervals = new LinkedHashMap<Integer, TTInterval>();
    }


    /**
     * Checks if the provided time-interval (defined by startSlot and endSlot) coincides with any time- 
     *interval already assigned to the event.
     *
     * This method has to work in O(log(N)) (N = number of time intervals).
     * 
     * @param startSlot startpoint (inclusive) of the interval to check
     * @param endSlot endpoint (inclusive) of the interval to check
     * 
     * @return true, if there is a collision, otherwise false
     */
    private boolean conflictingInterval(int startSlot, int endSlot) {
        boolean result = false;
        while ((startSlot <= endSlot) && !result) {
            result = intervals.containsKey(startSlot);
            startSlot++;
        }
        return result;
    }

    /**
     * Adds the given time interval to the event (defined by startSlot and endSlot)
     * 
     * This method has to work in O(log(N)) (N = number of time intervals).
     * 
     * @param startSlot startpoint (inclusive) 
     * @param endSlot endpoint (inclusive) 
     * 
     * @pre endSlot &ge; startSlot
     * @pre startSlot &amp; endSlot &ge; 0
     */
    void addTimeInterval(int startSlot, int endSlot) {
        assert startSlot <= endSlot;
        assert startSlot >= 0;
        assert !conflictingInterval(startSlot, endSlot);

        intervals.put(startSlot, new TTInterval(startSlot, endSlot));
    }

    /**
     * Removes the time interval referenced by the startpoint and returns the removed time interval
     *
     * This method has to work in O(log(N)) (N = number of time intervals).
     * 
     * @param startSlot startpoint
     * @pre startSlot &ge; 0
     * @return the removed time interval, or null, if there was none
     */
    TTInterval removeTimeInterval(int startSlot) {
        assert startSlot >= 0;

        return intervals.remove(startSlot);
    }



    /**
     * If the given time point is used by the event, then the time interval which includes the time point 
     * is returned
     * 
     * This method has to work in O(log(N)) (N = number of time intervals).
     * 
     * @param timeslot the time point to look for
     * @pre timeslot &ge; 0
     * 
     * @return time interval which includes the time point, or null, if there is none
     */
    public TTInterval getIntervalContaining(int timeslot) {
        assert timeslot >= 0;

    }


    /**
     * Returns the (time wise)  first time interval which has the duration to look for.
     * 
     * This method has to work in O(log(N)) (N = number of time intervals).
     * 
     * @param duration - exact duration of the time interval to look for (in time slots)
     * @pre duration &gt; 0
     * 
     * @return First time interval with the specified duration, or null, if there is none
     */
    public TTInterval getfirstIntervalByDuration(int duration) {
        assert duration > 0;
    }


    /**
     * Returns the (time wise) first time interval which is the closest to the min-duration to look for 
     * (so the time interval with the shortest fitting min-duration)  So the duration of the returned 
     * time interval is equal or longer then the min-duration to look for.
     * 
     * This method has to work in O(log(N)) (N = number of time intervals).
     * 
     * @param minDuration exact duration of the time interval to look for (in time slots)
     * @pre minDuration &gt; 0
     * @return First time interval with the desired minduration or longer, or null, if there is none
     */
    public TTInterval getfirstIntervalByMinDuration(int minDuration) {
        assert minDuration > 0;
    }


    @Override
    public String toString() {
    }

}

If I understood your question correct, I'd suggest using a List as data structure, because it's expandable and you're able to get a sorted representation of it fairly easy. Also I would suggest you to sort your List(s) as well as for the search problems I'd suggest using Binary search since its O(log n). So if you're inserting elements into your list search their respective position and use List.add(index,element) Oracle Doc to add it at said position. Same goes for searching elements, just without the adding.

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