Interview Question for Software Engineer / Developers


Country: United States




Comment hidden because of low score. Click to expand.
3
of 3 vote

struct Meeting {
	int start;
	int end;
	Meeting(int s, int e) {start=s; end=e;}
};

bool mysortfunc(Meeting a, Meeting b) { return a.end<b.end; }

int compute_min_confrooms(vector<Meeting>& meetings)
{
	// sort meetings w.r.t. their end times
	sort(meetings.begin(),meetings.end(),mysortfunc);

	int peak = 0;
	queue<Meeting> Q;
	Q.push(meetings[0]);
	for(int i=1; i<meetings.size(); i++) {
		while(!Q.empty() && Q.front().end < meetings[i].start) { Q.pop(); }
		Q.push(meetings[i]);
		peak = max(peak, (int)Q.size());
	}

	return peak;
}

- Anonymous February 15, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

How does this approach sound like?
Assumptions:
- Meetings start at 8:00 AM and end at 6:00 pm (this can be changed to a 24 hour as well, but just for brevity).
- Meeting minimum time is 15 minutes, so that means each hour will have 4 divisions.
- 8 to 6 = 10 hours = 10 * 4 = 40 divisions total.

Now,
Assign each time slot a digit, alphabet, code, whatever... for now lets say a digit.

So if a meeting is scheduled from 10-10.30 am, so we'd add 9 and 10 into the HashSet.
(Logic: 8-8.15 = 1, 8.15 - 8.30 = 2, 8.30 - 8.45 = 3, ....... 10-10.15 and 10.15-10.30 = 9 and 10... and so on)

Now let's say someone tries to find a meeting from 10.15-10.45, we'll look for codes 10 and 11. The HashSet already has the entry 10, so that's a collision right there!

Time complexity to 'look up' = O(1), time complexity to add all the meetings from the arraylist = O(n).

- parikksit.b March 09, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I will hire you. I just wrote an answer that is just that w/o seeing yours. Darn right you are.

- NoOne April 23, 2020 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can't you just count how many meeting objects you have? Can't they all be in the same room? Maybe I don't understand the problem. We're not given information on the capacity of room and such.

- Johnb February 12, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Well if 2 meetings have overlapping times, then you need 2 rooms for them. But if they don't overlap, then 1 room suffice. So the question is about finding the maximum number of overlapping meetings at any given time.

- Sunny February 12, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Let's take an example to understand the question. I am not using long for start and end times, just using int for simplicity.

M1: 9-10
M2: 10-11
M3: 10:30-11
M4: 12-1

If you observe, total amount of conference rooms required are just 2 for all the meetings. That's because you can use the same room for M1 and M2, but since M3's start time is less than M2's (or other active meetings) end time, you will have to grep a new conf room. And as for M4, the meeting starts after all the 3 meetings are over. Hope that clarifies the question.

My solution was to sort the meetings by start times. As you iterate through the meetings, add the end times to the min-heap by key = end time. Then for each iteration, check if startTime of current meeting < extract-min(heap). If so, you will increment the counter for counting conference rooms.

Complexity will be O(nlogn). That's because the loop runs for n times and heap operation is O(logn). And sorting the input vector of conference rooms by start times takes O(nlogn). So, overall complexity is O(nlogn). I think this is optimal. It is a problem discussed in algorithms book of Eva Tardos (found it after interview)

- animageofmine February 12, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Well, this took me much much longer than it should have, but here is my solution:

public struct Meeting
{
    public long startTime;
    public long endTime;

    public Meeting(long sTime, long eTime)
    {
        startTime = sTime;
        endTime = eTime;
    }
}

public class Room
{
    public List<Meeting> meetings;

    public Room()
    {
        meetings = new List<Meeting>();
    }
    public bool try_schedule_meeting(Meeting meeting)
    {
        foreach (Meeting scheduledMeeting in meetings)
        {
            if ((meeting.startTime < scheduledMeeting.endTime) && (meeting.endTime > scheduledMeeting.startTime))
                return false;
        }
        
        meetings.Add(meeting);
        return true;
    }
}

public class Scheduler
{
    List<Room> rooms;

    public Scheduler()
    {
        rooms = new List<Room>();
    }
    public List<Room> schedule_meetings(List<Meeting> meetings)
    {
        for(int i = 0; i < meetings.Count; ++i)
        {
            bool IsMeetingScheduled = false;
            foreach(Room room in rooms)
            {
                if (room.try_schedule_meeting(meetings[i]))
                {
                    IsMeetingScheduled = true;
                    break;
                }
            }

            if(!IsMeetingScheduled)
            {
                Room newRoom = new Room();
                newRoom.try_schedule_meeting(meetings[i]);
                rooms.Add(newRoom);
            }
        }

        return rooms;
    }
}

static void Main(string[] args)
{
    List<Meeting> meetings = new List<Meeting>();
    Meeting m1 = new Meeting(8, 10);
    Meeting m2 = new Meeting(9, 10);
    Meeting m3 = new Meeting(10, 11);
    Meeting m4 = new Meeting(8, 12);

    meetings.Add(m1);
    meetings.Add(m2);
    meetings.Add(m3);
    meetings.Add(m4);

    Scheduler s = new Scheduler();
    List<Room> rooms = s.schedule_meetings(meetings);

    Console.WriteLine("Number of Rooms: {0}", rooms.Count);

    int i = 1;
    foreach(Room r in rooms)
    {
        Console.WriteLine("Room: {0}", i++);

        int j = 1;

        foreach(Meeting m in r.meetings)
        {
            Console.WriteLine("Meeting: {0}", j++);
            Console.WriteLine("\tStart: {0}", m.startTime);
            Console.WriteLine("\t  End: {0}", m.endTime);
        }
        Console.WriteLine();
    }
}

Test Output:

Number of Rooms: 3
Room: 1
Meeting: 1
Start: 8
End: 10
Meeting: 2
Start: 10
End: 11

Room: 2
Meeting: 1
Start: 9
End: 10

Room: 3
Meeting: 1
Start: 8
End: 12

- Evan February 12, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This one is a brute force algorithm.

Also, why are you returning back after this check:
{
if ((meeting.startTime < scheduledMeeting.endTime) && (meeting.endTime > scheduledMeeting.startTime))
return false;
}

You are not iterating through each scheduled meeting. I think my solution so far O(nlogn) time seems to be better (see above)

- animageofmine February 13, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

You would return because if the meeting to be scheduled overlaps with a meeting previously found in that room, you wouldn't be able to schedule the new meeting in that room as it conflicts with an existing meeting and would have to move to the next room.

- Anonymous February 13, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

But, yes, this problem can be solved in O(n log n) with sorting.

- Anonymous February 13, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here's the c++ version:

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

bool timeLess(int a, int b) 
{
    int d = abs(a) - abs(b);
    if (d == 0)
        return a < b;
    
    return d < 0;
}

struct Meeting {
    int start;
    int end;
};

int main(int argc, char**argv)
{
    Meeting allMeetings[] = {
        {1, 3},
        {2, 4},
        {6, 7},
        {4, 6}, 
        {5, 6}
    };
    
    int N = sizeof(allMeetings) / sizeof(allMeetings[0]);
    
    vector<int> times;
    
    for (int i = 0; i < N; i++) {
        times.push_back(allMeetings[i].start);
        times.push_back(-allMeetings[i].end);   
    }
    
    sort(times.begin(), times.end(), timeLess);
    
    int rooms = 0;
    int maxRooms = 0;
    
    for (int i : times) {
        if (i > 0) {
            // hit the meeting start time
            rooms++;
            if (rooms > maxRooms)
                maxRooms = rooms;
        }
        else {
            // hit the meeting end time
            rooms--;
        }
    }
    
    cout << "max number of rooms needed is " << maxRooms << endl;
}

- Westlake February 12, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Actually this problem is a variation to question 15551781, for which there exists Marzullo algorithm.

- Anonymous February 13, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

If all trivial algorithms got a name, then the names would end up being useless.

- Kadane. February 13, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Complexity should be o(n*log(n)) + o(n*m) , by which n is the number of meetings, and m is the max meeting room number.

package com.cc.question;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;


class Mtg 
{ 
	long startTime; 
	long endTime;
	Room room;
	public Mtg(long startTime, long endTime) {
		this.startTime = startTime;
		this.endTime = endTime;
	}
}; 
class Room{
	boolean isOccupied = false;
	Mtg occupiedMtg = null;
}

public class MtgScheduler  implements Comparator<Mtg>{
	
	private Mtg[] meetings;
	private List<Room> mtgRooms = new ArrayList<>();
	
	public MtgScheduler(Mtg[] meetings) {
		this.meetings = meetings;
	}
	
	
	public int minMtgRoomNum() {
		//sort meetings by startTime
		Arrays.sort(meetings,this);
		
		//iterate the meetings by start time, and schedule each of them
		for(int i=0;i < meetings.length;i++) {
			Mtg meeting = meetings[i];
			Room room = findVacancy(meeting);

			if(room == null) {
				room = allocateNewRoom();
			}

			room.isOccupied = true;
			room.occupiedMtg = meeting;

		}
		return mtgRooms.size();
	}
	public Room allocateNewRoom() {
		Room room = new Room();
		mtgRooms.add(room);
		return room;
	}
	
	//depend upon the meeting, release any room if the meeting is over; then find the vacancy;
	public Room findVacancy(Mtg meeting) {
		Room vacancyRoom = null;
		for(int i=0;i<mtgRooms.size();i++) {
			Room room = mtgRooms.get(i);
			if(room.isOccupied) {
				if(room.occupiedMtg.endTime<= meeting.startTime) // release the room if the meeting is over
				{
					room.isOccupied = false;
					room.occupiedMtg = null;
				}
			}
		}
		
		for(int i=0;i<mtgRooms.size();i++) {
			Room room = mtgRooms.get(i);
			if(room.isOccupied == false) {
				vacancyRoom = room;
				break;
			}
		}
		return vacancyRoom;
	}
	@Override
	public int compare(Mtg o1, Mtg o2) {
		if(o1 == null || o2 == null) 
			return 0;
		if(o1.startTime< o2.startTime)
			return -1;
		else if (o1.startTime> o2.startTime) {
			return 1;
		}
		return 0;
	}
}




// Test Case class
package com.cc.question;

import junit.framework.Assert;

import org.junit.Test;

public class SchedulerTest {
	@Test
	public void testScheduler() {
		Mtg[] meetings = {new Mtg(7, 10),new Mtg(11, 13), new Mtg(9, 11), new Mtg(11, 14), new Mtg(12, 13),new Mtg(13, 15),new Mtg(15, 16)};
		MtgScheduler scheduler = new MtgScheduler(meetings);
		int minMtgRoomNum = scheduler.minMtgRoomNum();
		Assert.assertEquals(minMtgRoomNum, 3);
	}
}

- Yaohuah February 21, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

How does this approach sound like?
Assumptions:
- Meetings start at 8:00 AM and end at 6:00 pm (this can be changed to a 24 hour as well, but just for brevity).
- Meeting minimum time is 15 minutes, so that means each hour will have 4 divisions.
- 8 to 6 = 10 hours = 10 * 4 = 40 divisions total.

Now,
Assign each time slot a digit, alphabet, code, whatever... for now lets say a digit.

So if a meeting is scheduled from 10-10.30 am, so we'd add 9 and 10 into the HashSet.
(Logic: 8-8.15 = 1, 8.15 - 8.30 = 2, 8.30 - 8.45 = 3, ....... 10-10.15 and 10.15-10.30 = 9 and 10... and so on)

Now let's say someone tries to find a meeting from 10.15-10.45, we'll look for codes 10 and 11. The HashSet already has the entry 10, so that's a collision right there!

Time complexity to 'look up' = O(1), time complexity to add all the meetings from the arraylist = O(n).

- parikksit.b March 09, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

int minConfRoomsII(vector<meeting*> endmeet)
{
	int current = 1;
	vector<meeting*> startmeet(endmeet);
	sort(endmeet.begin(), endmeet.end(), endcomp);
	sort(startmeet.begin(), startmeet.end(), startcomp);
	int maxcount = 1;
	int i = 1, j = 0;
	while(i < startmeet.size() && j < endmeet.size())
	{
		if(startmeet[i]->start < endmeet[j]->end)
		{
			current += 1;
			i++;
			maxcount = max(current, maxcount);
		}
		else
		{
			current -= 1;
			j++;
		}
	}
	return maxcount;

}

- mystery_coder May 25, 2018 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

@animageofmine
This is in-fact a 20-min question. You just need to increase the number of room when start time of next meeting is before end-time of previous meeting and keep track of global max.
Suppose meeting structure is: meet (ST, ET) (ST: start time and ET: end time)
1. sort the meetings in order of start time
2. initially, number of meeting room rooms=1, max_rooms=1;
3.

from (j=0,i=1; i<n;i++) (when order starts from 0) {
      while (meeting[i].ST < meeting[j].ET) 
		{ rooms++; i++;}
      if (rooms > max_rooms) 
		max_rooms = rooms;
      j++;
   }

return max_rooms;

- alanturing06022014 January 15, 2019 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

We do not require sorting at all. No need. Using sorting, things are incredibly easy. There is a neat and fun way of solving this.

/* 
If the precision of the meetings are in integers
that is 2:30 to 3:30, then we can simply quantize
the minimal value which is 30 mins meeting time min.
Then the problem becomes finding the time quantum of 30 mins 
which contains the maximum overlap of meetings.
We encode the time 11:30 as 11.5 -> 115 and take a 5 as 30 mins.
This can easily be done.
This can be solved in Theta(N). Observe:
*/
def find_min_rooms( list_of_meetings ) {
  // simply carry on a counter ...
  counter = dict()
  for ( meeting : list_of_meetings ){
     for ( s = meeting.start * 10 ; s <= meeting.end * 10 ; s+= 5 ){
       counter[s] += 1 ?? counter[s] = 1 
     }
  } 
  #(m,M) = minmax( counter.values )
  return M 
}

- NoOne April 23, 2020 | Flag Reply
Comment hidden because of low score. Click to expand.


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More