【发布时间】:2019-11-29 21:13:33
【问题描述】:
我已经给出了这两个类(在代码块下面),我必须在不再是 O(log(N) 的时间内实现给定的 TTEvent 方法。我可以使用以下数据结构:
- Integer[] - 起点或持续时间数组
- 列出、排队、出列或设置起点或持续时间
- 地图 - 起点到终点或持续时间的映射
- 地图 - 起点到时间间隔的映射
- TTinterval[] - 时间间隔数组
- 列出、排队、出列或设置时间间隔
其中还有一些持续时间到 xyz 的映射,但由于持续时间不是唯一的,我立即排除了这些。
我可以使用链表、数组列表、哈希图等子类型。
我似乎找不到合适的数据结构来使用。我大部分时间都坚持通过持续时间的方法。我能想到的在这些结构中查找数据的所有方法都会比 O(log(N),主要是 O(N) 慢,因为我会循环或在地图上调用 .contain(value)。
假设 N 会大而不是小。
现在我不想要一个解决方案,而是一些关于什么是最需要使用的结构的指针,也许还有一些专门关于通过持续时间的方法的提示。
Java 编译器必须是 1.8,如果这有什么不同的话(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 ≥ startSlot
* @pre startSlot & endSlot ≥ 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 ≥ 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 ≥ 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 > 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 > 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() {
}
}
【问题讨论】:
-
那么哪些方法需要在 O(log(n)) 内?
-
TTEvent 的所有方法,都有“此方法必须在 O(log(N)) 中工作(N = 时间间隔数)。”在评论中。我从类中排除了所有其他方法,所以它应该是几乎所有方法。
标签: java list dictionary collections set