vector<Interval> employeeFreeTime(vector<vector<Interval>>& schedule) { vector<Interval> ans; if(schedule.size() == 0){ return ans; } vector<Interval> allIntervals; for(vector<Interval> freeTimes : schedule){ for(Interval freeTime : freeTimes){ allIntervals.push_back(freeTime); } } sort(allIntervals.begin(), allIntervals.end(), cmp); int curIntervalEndTime = allIntervals[0].end; for(int i = 1; i < allIntervals.size(); ++ i){ int nextIntervalStartTime = allIntervals[i].start; if(curIntervalEndTime < nextIntervalStartTime) { Interval freeInterval(curIntervalEndTime, nextIntervalStartTime); ans.push_back(freeInterval); } curIntervalEndTime = max(curIntervalEndTime, allIntervals[i].end); } return ans; }
static #endif void traverseLcpTree(Int64 *lcpTab, Int64 *sa, Sequence *seq, Int64 numOfSubjects, Int64 numOfQueries, Int64 *seqBorders , Int64 *leftBorders, Int64 *strandBorders , queryInterval ***listQueryIntervalsFwd // lists of query intervals, there are |Q| lists , queryInterval ***listQueryIntervalsRev // lists of query intervals, there are |Q| lists , Int64 maxDepth, Int64 *maxShulens , queryInterval ***fastSearch, Int64 *lastIndex, qNode ***root) { Interval *lastInterval, *interval; Int64 i, j, lb, rightEnd, lastIsNull; //Int64 numOfChildren; Stack *treeStack = NULL; Stack *reserveStack = NULL; // reserve stack for intervals Stack *reserveQIStack = NULL; // reserve stack for query intervals short *QS; /* array of subject and query indexes corresponding to each position in the SA; pos. values --> subjects, neg.values --> queries */ //queryLeaves - maximal number is the maximal number of leaves at each interval; queryLeaves[i][0]-query index, queryLeaves[i][1]-position in a query Int64 queryLeaves[MAXNUMLEAVES][2]; //queryLeaves[i][0]-query index, queryLeaves[i][1]-position in a query int maxCols = 2; int step = STEP; queryInterval *qi = NULL; qNode *qn = NULL; // unresolvedQLeaves - unresolved leaves from the interval's subtree; unresolvedQLeaves[i][0]-query index, unresolvedQLeaves[i][1]-position in a query Int64 *unresolvedQLeaves = NULL; Int64 maxUnresQLeaves = 100; unresolvedQLeaves = emalloc(maxUnresQLeaves * sizeof(Int64) * 2); // * 2 since each leaf is represented by ints query index and a position within a query /* allocate 2 lists of |Q| pointers; one list is the beginning and the other is end of the list */ if (BSEARCH) { *root = getBTQueryIntervals(numOfQueries); } else { *listQueryIntervalsFwd = getListQueryIntervals(numOfQueries); *listQueryIntervalsRev = getListQueryIntervals(numOfQueries); } /* initialize auxiliary arrays: subjects and queryLeaves */ QS = getQS(seqBorders, leftBorders, numOfSubjects, numOfQueries, step); //queryLeaves = getQueryLeaves(&numQueryLeaves, &maxNumLeaves); sa++; /* since data in sa and lcpTab start with position 1, and not 0 */ lcpTab++; rightEnd = seq->len-1; lcpTab[0] = 0; /* or -1 */ treeStack = createStack(); /* true stack */ lastIsNull = 1; lastInterval = NULL; interval = NULL; push(treeStack, getInterval(0, 0, rightEnd, NULL, numOfSubjects, NULL, maxDepth)); /* push root node to the stack */ /* auxiliary stack for (Interval *); used for saving used allocated locations; since stack operations pop/push are faster than malloc */ reserveStack = createStack(); /* auxiliary stack for (queryInterval *) */ reserveQIStack = createStack(); for (i = 1; i < seq->len; i++){ lb = i - 1; while(lcpTab[i] < ((Interval *)(treeStack->top))->lcp) { /* end of the previous interval, so the interval should be popped from the stack*/ /* if the current top is the child of the new node, then pop the top */ ((Interval *)(treeStack->top))->rb = i - 1; lastInterval = (Interval *)pop(treeStack); process2(lastInterval, *listQueryIntervalsFwd, *listQueryIntervalsRev, seqBorders, leftBorders, strandBorders, numOfSubjects, QS, step, &queryLeaves[0][0], maxCols, sa, &unresolvedQLeaves, &maxUnresQLeaves, reserveQIStack, maxShulens, fastSearch, lastIndex, *root); lb = lastInterval->lb; /* save child intervals of popped interval */ for(j = 0; j < lastInterval->numChildren; j ++) { lastInterval->children[j]->numChildren = 0; lastInterval->children[j]->parent = NULL; push(reserveStack, (void *)lastInterval->children[j]); } lastIsNull = 0; if (lcpTab[i] <= ((Interval *)treeStack->top)->lcp) { /* the new top is the parent of the ex top*/ lastInterval->parent = treeStack->top; addChild((Interval *)treeStack->top, lastInterval); lastIsNull = 1; } } /* end while */ if (lcpTab[i] > ((Interval *)treeStack->top)->lcp) { /* add interval to the stack */ if (isEmpty(reserveStack)) { //interval = getInterval(lcpTab[i], lb, rightEnd, NULL, numOfSubjects, treeStack->top, maxDepth);// treeStack->top or null interval = getInterval(lcpTab[i], lb, rightEnd, NULL, numOfSubjects, NULL, maxDepth); } else { /* use locations from the reserveStack */ interval = pop(reserveStack); // pop the last child of the lastInterval from the reservestack interval->lcp = lcpTab[i]; interval->lb = lb; interval->rb = rightEnd; interval->numChildren = 0; interval->parent = NULL; } if (!lastIsNull){ lastInterval->parent = interval; addChild(interval, lastInterval); lastIsNull = 1; } push(treeStack, interval); } } #if DEBUG printf("Empting stack...\n"); printf("Number of intervals allocated:%lld\n\n", (long long)numInterval); #endif while(!isEmpty(treeStack)) { interval = pop(treeStack); /* when the stack is not empty and the current interval has no parent, then his parent is on the top of the stack*/ if (!isEmpty(treeStack) && !interval->parent && interval->lcp > ((Interval *)(treeStack->top))->lcp) { interval->parent = treeStack->top; addChild((Interval *)treeStack->top, interval); } /* process: * 1) it labels an interval according to whether it has ST leaves from query (isQuery) or from subject (isSubject) or both (isQuery && isSubject). * 2) if(isQuery && isSubject) it determines the corresponding query shustring lengths (if any) */ process2(interval, *listQueryIntervalsFwd, *listQueryIntervalsRev, seqBorders, leftBorders, strandBorders, numOfSubjects, QS, step, &queryLeaves[0][0], maxCols, sa, &unresolvedQLeaves, &maxUnresQLeaves, reserveQIStack, maxShulens, fastSearch, lastIndex, *root); for (i = 0; i < interval->numChildren; i++) { freeInterval((void *)interval->children[i]); } interval->numChildren = 0; if (!interval->parent) { freeInterval((void *)interval); } } //freeInterval((void *)interval); /* free the root interval; it has to be done here, what is different from kr 2!! */ freeStack(treeStack, freeInterval); /* free memory allocated for the reserveStack */ while (!isEmpty(reserveStack)) { interval = pop(reserveStack); for (i = 0; i < interval->numChildren; i++) { freeInterval((void *)interval->children[i]); } //freeInterval((void *)interval); /* free the root interval */ if (!interval->parent) { freeInterval((void *)interval); } } /* free reserve stack */ freeStack(reserveStack, freeInterval); /* free reserve queryInterval stack */ if (BSEARCH) { while (!isEmpty(reserveQIStack)) { qn = pop(reserveQIStack); qn->left = qn->right = NULL; freeQNode(qn); } freeStack(reserveQIStack, freeQNode); } else { while (!isEmpty(reserveQIStack)) { qi = pop(reserveQIStack); qi->next = qi->prev = NULL; freeQueryInterval(qi); } freeStack(reserveQIStack, freeQueryInterval); } #if DEBUG printf("Finished.. Number of intervals allocated:%lld\n\n", (long long)numInterval); #endif free(QS); free(unresolvedQLeaves); //printf("maxUnresQLeaves = %d\n", maxUnresQLeaves); }