Facebook Interview Question for Software Engineer / Developers


Country: United States
Interview Type: In-Person




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

i doubt this is a real FB interview question because the problem statement is exactly the same as appears in a textbook:
http: // web.engr.illinois.edu/~jeffe/teaching/algorithms/notes/05-dynprog.pdf
see page 22 problem 10. an exercise of DP. probably some student who tries to figure out the solution posted it here :(

- Anonymous January 23, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

I think this problem can be solved using Dynamic Programming with O(N^2) time and O(N^1) space. (BUT I CAN BE WRONG...)

Assume it takes constant time to determine whether 2 lines intersect or not.

Consider case where there are N lines and the maximum subset of N lines among which no lines intersect is S(N).

Now let's add the (N+1)th line. The maximum subset of (N+1) lines among which no lines intersect, i.e. S(N+1), can only fall into following 2 case:
1) The (N+1)th line is not in S(N+1).
In this case, S(N+1)_case1 = S(N)

2) The (N+1)th line is in S(N+1).
In this case, in N iterations, we find out the lines which will intersect with the (N+1)th line, denoted by I(N+1). Then we exclude above lines from S(N), which gives S(N+1)_case2 = S(N) + (N+1)th line - I(N+1).

Then, the final S(N+1) must be max(S(N+1)_case1, S(N+1)_case2).

In sum, for each line we need N iterations to find out I(N) and we need a length-N array to store S(N), hence O(N^2) run time complexity and O(N^1) space.

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

Above algorithm needs revision because I failed to consider that S(N) may not be unique.

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

Consider 5 segments: 2 vertical and 3 horizontal. In other words, we have the following intersecting pairs:
(1, 3)
(1, 4)
(1, 5)
(2, 3)
(2, 4)
(2, 5)

According to this approach, I believe we will have:
S(1) = {1}
S(2) = {1, 2}
S(3) = {1, 2}
S(4) = {1, 2}
S(5) = {1, 2}

So we would picked the 2 vertical ones instead of the 3 horizontal ones.

The equation for S(N+1)_case2 = S(N) + (N+1)th line - I(N+1) should raise a red flag, because basically it's adding 1 line but taking away potentially many. S(N+1)_case2 would only be greater than S(N+1)_case1 if the N+1 line doesn't intersect with any line in S(N). So this is basically a greedy algorithm.

- Sunny November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 4 vote

EDIT: this is actually wrong, see anantpushkar009's comments for discussion

A key insight is that this problem is the same as unweighted interval scheduling, just around a circle. Consider two line segments l1 and l2 represented by the following points:

l1: (p1, p2)
l2: (p3, p4)

The only way that these line segments intersect is if p2 is "further along" on the unit circle than p3 or p4 is "further along" on the unit circle than p1. An nice way to represent distance on the unit circle is radians, which we can get by taking the inverse tangent of each point! One subtlety is that we need to normalize the tangent to a certain range: I'll use 0 to 2pi. In python:

import math

def arctan(x, y):
	atan = math.arctan2(x, y)
	while atan < 0:
 		atan += 2 * math.PI
	while atan > 2 * math.PI:
		atan -= 2 * math.PI
	return atan

def transform(L):
	transformed = list()
	for line in L:
		new_point = list()
		for x, y in line:
			new_point.append(arctan(x, y))
		transformed.append(new_point)
	return transformed

Now that we have a "transformed" set of line segments, each with a start and finish angle, the problem is identical to the greedy algorithm for maximum interval scheduling. Sort all the line segments by order of finish angle, add each line segment one at a time and remove all conflicting line segments with each iteration. (see an algorithms textbook for a proof):

def no_intersection(L):
	T = transform(L)
	T = sorted(T, key=lambda segment: segment[1]) # sort by finish angle
	result = list()

	i = 0
	while i < len(T):
		result.append(T[i])

		# find the next nonconflicting interval
		j = i
		while j < len(T) and T[j][0] < T[i][1]: 
			j += 1
		i = j
	
	return result

If you wanted the original line segments, you could also store the mappings in a hash table in the transforming step.

Time complexity is O(nlogn) for the sorting step in the greedy algorithm

- yoavzimmerman November 02, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

Though the idea seems nice but I see 2 problems:

1. Minor problem: Interval scheduling works because start<end for all interval. The question no where states that the lines will be given such that start point will subtend smaller angle than the end point wrt x-axis. You seem to have made no effort to ensure that start angle < end angle for all intervals (consider a line segment starting at 0.9,-0.436 and ending at 0.9,0.436: we would rather prefer the other way round for interval scheduling to work here, otherwise, we get stuck in an infinite loop). This can be easily fixed by sorting new_point before appending it to transformed.

2.Major problem: Consider the following example:

#angles in degree
transform(L) = [
			[30 , 150],
			[120,200],
			[190,300],
			[220,310],
			[60,320]
			]

If I understand you correctly, you will end up returning: [ [30,150] , [190,300]], even if the answer is: [[60,320] , [120,200] , [220,310]].

- anantpushkar009 November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

I think idea is okay, the only difference is that unlike a real segment on a 1-dimension line, the segment on a circle has its "extreme", just the like the above example, the [60 320] should not treated as it is, but a transformation to [320 420] since they are the same on a given circle. And after such a transformation, the algorithm would give the right answer.

- Yang November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

hi,

I was thinking of the same approach but instead with a different transformation: "projecting all the segment points to the ox axis"

- CostelRadulescu November 21, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

This idea builds up from the solution given by yoavzimmerman (by reducing the given problem to unweighted interval scheduling problem by using angles instead of points). The problem with that was, it failed because of cyclic nature of intervals. We can get through that in the following way:
1. If there exists an angle at which no line exists, ie, if there exists theta such that a ray from origin at theta wrt x-axis passes through no line, we rotate x-axis by angle theta. Now we no more have any cyclic nature in the intervals.
2. If the above does not exist, we choose a pair of lines that intersect, say l1 and l2. Both of these can not be together in a solution. So, we apply interval scheduling on L-l1 and L-l2 (both of these set will satisfy the condition#1) and return the max of these two.

To check existence of theta, run a line sweep algorithm[O(n)]. The rest can be done in nlogn time. So, total complexity nlogn.

EDIT : As in the worst case, every ray from origin might intersect O(n) number of lines, the worst case complexity will be O(n^2 * logn)

- anantpushkar009 November 02, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

Good catch, completely missed that problem.

I think you're very close, but I'm still not convinced that there are always a pair of lines that you can remove to make two subsets that satisfy condition #1. What about an extremely dense line segment set such as the following? (excuse the crude drawing, but I think it gets the point across)

i.imgur.(com)/AbhWaQd.png

We could draw try picking a random ray from the origin, then running interval scheduling on L-l for every line segment l that intersects it, then taking the max. I think that breaks the time complexity to O(n^2logn) though.

Thoughts?

- yoavzimmerman November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

You are right, I cannot think of a way to eliminate the need to remove every line and run the algorithm separately .As in worst case we may not have any angle that intersects less than O(n) lines ,the worst case complexity will be O(n^2 * logn)

- anantpushkar009 November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

After remove the first line, we don't have a good reason to remove another one. It's hard to argue both of them should not be in the solution. So it's hard to remove every line.

Instead of selecting starting point, we can select starting segment. Select one segment, consider all the segment intersecting with it. If all the intersected neighbors are not in the solution, then it must be in the solution. So we need to try all the neighbors and itself as starting segment, and find the best solution.

To improve speed, we may want to start with a segment with small number of neighbor. But I'm not quite sure how difficult it is compared to the original question.

- Chenliang Xu November 07, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Now that I think about it, isn't this the same as finding the "maximum independent set", which is NP-hard?

To see this, first represent the line segments as a graph instead. Let each line segment be a vertex, and let there be an edge between 2 vertices if the corresponding line segments intersect. Isn't the original problem of finding the maximum subset of L equivalent to finding the maximum subset of vertices such that they cover the whole graph, without any 2 vertices being adjacent?

- Sunny November 02, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

(Just realized Anna's comment below also mentions largest independent set and that this is NP hard)

Whoever that votes down that solution should probably leave a reason why it's wrong.

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

Since "maximum independent set" can be reduced to what you just mentioned. Doesn't it make this also NP-hard?

- Starbucks Employee November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The segments are not arbitrary. It may be a special case of the maximum independent set problem.

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

@Starbucks: No, because NP-hardness is established by taking an NP-hard problem and reducing it to the current problem in poly-time. Reducing the current problem to an NP-hard problem proves nothing. In fact, the whole point of NP-complete problems is that any problem in NP can be reduced to them in poly-time, so it's completely unsurprising if you should find such a reduction.

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

Isn't this what Starbucks just said? Reducing Max independent set to this?

- guruqu November 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I was wrong.

- anonymous November 03, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I don't quite get the point why there's no optimal substructure. Do you have a counter example to guruqu's DP solution?

- Starbucks Employee November 03, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

If a line were to be in optimal solution, since no other line should cross such line in a valid solution, it separate all end-points into two disjoint sets (smaller sub-problem), hence feasible for a divide-and-conquer approach.

- Starbucks Employee November 03, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Let the lines be L1, L2,L3, ..., Ln. One idea is to define the sub problem as D(i, j, k) = max # of non intersecting line segments between Li & Lj using { L1, L2, ..., Lk }, then

D(i, j, k) = 0 if Li and Lj intersects (can be O(1))
max(D(i, j, k-1), D(i, k, k-1)+D(j, k, k-1))

Let F(i, j) =- D(i, j, n)

then for each Li, we find max F(i, j) among all Lj's that are on one side of Li
+max F(i, j) among all Lj's that are on the other side of Li

Do this for each Li, and record the max

O(N^3)

- josda November 03, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

After digesting the comments by guruqu & gen-y-s, here's how I understood the dynamic programming solution.

(1) First convert each point to some angle such that they can be sorted, while keeping track of which segments they correspond to - O(n)
(2) Sort the angles - O(nlogn)
(3) You should now end up with an array (eg. [5 2 3 4 2 1 4 3 5 1]). The numbers correspond to the line segments.
(4) Note that in the example above, {534} is the solution. Also notice how the "longest non-contiguous palindrome" in the array is 5x34xx435. It should be easy to see that the numbers constituting the "longest non-contiguous palindrome" are actually the same line segments as the solution.
(5) Finally, due to the cyclic nature, the array could have been shifted like [2 3 4 2 1 4 3 5 1 5] instead. To accommodate this, you actually need to find the 2 "longest non-contiguous palindromes" in the array. In this case they are 34xx43 and 5x5. So the solution is simply the line segments from the 2 "longest non-contiguous palindromes".
(6) The optimal substructure should now be obvious. Basically DP[i][j] contains the optimal solution from point i to point j (inclusive). You then build the DP matrix starting from length 1 to 2n. At each step, set DP[i][j] = (arr[i] == arr[j] ? 1 : 0) + (max(DP[i][k] + DP[k+1][j]) for k=i to j-1). Populating this matrix requires O(n^3) time.

The algorithm takes O(n^3) time and O(n^2) space. Hope I haven't missed anything.

- Sunny November 05, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Recursive procedure:
For each segment s do:
[segment s had broken circle into two sectors, s1 and s2]
run recursive procedure on segment set that fully fit in s1 and similarly with s2, sum them up and plus one for selected one.
Select max sum from for loop and return

Note. in the second recursion and on, selected segment will be breaking current sector into 3 sectors, so sum up from 3 recurcsive procedures.

Time analizes:

T(n) = n * 3T(n/3)
T(1) = 1

n^log n. Which is better than exponentional needed for straight forward solution to coloring problem.

Now, we can enhaunce solution to each sector with caching. There should be O(n^2) of such sectors, so the time complexity should be O(n^2) because all the time solving this we are filling each cache entry and once done, the rest will complete.

- CT November 06, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

As discussed earlier, convert to angles. Now, _if there is a point_ on the circle which does not belong to any segment, rotate the set so that it become 0. Now we've got a "movie scheduling problem" from Skiena's book, which is solved by selecting the interval with the leftmost right border, eliminating intersections and then repeting until all the intervals are considered. Should be n*log(n).

The next is a wild guess, haven't had time to think over yet:
If there is _no such a point_, maybe something like this will work: rotate so that the smallest sector starts at 0, apply the algorithm, above; then revert angels (i.e. go clockwise), so that we start from another side of the smallest sector and go opposite direction; repeate the algorimth and choose the best of two results.
If there are multiple minimums, we may repeat it for each, so it's n^2. (However, not sure still if this is accurate for border conditions)

- be1ca November 08, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thank for bringing up movie scheduling problem. The way I see the difference, the movie that starts after other movie starts but finishes before is not conflicting. Therefore I say that we recurse into 3 time intervals: before start, during movie, after movie. With the exception of first step that breaks circle into two. And instead of removing I am interested in the set of segments that begin and end within current sector. You can take a look at my solution. I like yours a lot, just don't understand the need for rotation.

- CT November 09, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This problem is O(n^2) solvable
take a point on the circle (0,1) say.. now for each line get the two angles formed from the two end points w.r.t x axis, say (alpha, beta) such that alpha<beta so for each line you will get these angles (a0,b0), (a1,b1), (a2,b2)....
sort them on their first index(O(nlogn) and then find the largest non-decreasing sequence on the second index..O (n^2)

- kkr.ashish November 12, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

the alpha beta are arranged to be alpha<beta by switching the two end points

- kkr.ashish November 12, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is actually a conceptually simple problem to solve.

Since the lines are all on the unit circle, each line bisects the circle into two halves. For example, a horizontal (-1,0 to 1,0) line bisects the circle into 0->180 and 181 -> 359 degrees.

All lines that will intersect with this one must have one vertex in the first half and one vertex in the second. In the previous example, suppose we have a line where one vertex is at angle 90. If the line intersects then the second vertex must be between 181 and 359, Otherwise, the line is conceptually on the top of the unit circle and will not intersect.

Once this comparison is found, we can build a simple n^2 algo to search for lines that don't intersect anything. We have to leave the intersected lines in because there may be another line further in the list that only intersects with this one.

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

My solution is based on the same observation. Because each segment creates two disjoint subset of segments that don't intersect it, divide and conquer solution is easy. You are welcome to take a look.

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

Observation : 2 lines(x1,y1), (x2,y2) intersect iff on the circle x2 comes between x1 and y1 or wise verse. Assume all the lines are maked as (x1,y1), (x2,y2).....(xn,yn)

1. start from any point on the circle and move along the circle(circumfrance) to come back to same point, along the path keep the sequence of xi's as they come in the path.
2. Now again do the same process in the opposite direction but this time keep track of sequence of yi's along the path.
now you name 2 sequances one of xi's and other yi's

now find the maximum matching sequence for (xi's ,yi's ) which will give you subset of maximum lines without overlap.

- Paras November 18, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Also easily draw all the lines in a matrix marking each point with the line object and if there are more than one passing in the same matrix put in a structure where for each intersection is represented.

Another way is to convert each point as either a degrees or radian point in the circle. In this way we can say a line intersect if in between a line starts in A and ends in B there are another point that starts in between A & B but end outside A & B.

For example if Line (A, B) and Line (C,D) if in degrees do not intersect if you find them in the following orders ABCD, ACDB or CABD in that orders in radians or degrees otherwise the they intersect when they are like ACBD, CADB

Using recursion to find the largest subset

- Nelson Perez January 05, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

We can sort all endpoints by angle (y = sin(a), x = cos(a)).
Then we can build a graph where vertices are lines,edges are intersections. It is possible to do in O(n). So now we need to find the largest independent set. It is NP hard.
One of possible heuristics is to find the most low-degree vertex, add it to the set, delete it and its neighbours from the graph. Repeat until it is possible.

- Anna November 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Dynamic Programming. Should be O(n^3) time and O(n^2) space.
State would be two dimensional DP(i,j) standing for maximum segments that can fit into [i,j].
State transition would be base on first segment of optimal solution in range [i,j].
DP(i,j) = argmax_k (1+DP(k_start+1,k_end-1)+DP(k_end+1,j)), seg k that fits in [i,j].
Mind some boundary cases, and hopefully this is clear enough for you guys.

public static class Point {
  public double x, y;

  public Point(double x, double y) {
    this.x = x;
    this.y = y;
  }
}

public static int MaxSetDP(int[] segs) {
  int n = segs.length;
  if (n == 0)
    return 0;

  int[][] dp = new int[n][n];
  for (int i = 0; i < n; i++) {
    for (int j = i; j >= 0; j--) {
      int max = 0;

// For segment [i,j] search through all segments that fits in [i,j]
// assuming it's the first segment for opitmum solution
// Find the segments with largest fit

      for (int k = j; k < i; k++) {
        if (segs[k] >= 0 && segs[k] <= i) {
          int cmax = 1;
          if (segs[k] - k > 2) {
            cmax += dp[k + 1][segs[k] - 1];
          }
          if (segs[k] < i) {
            cmax += dp[segs[k] + 1][i];
          }
          max = Math.max(max, cmax);
        }
      }
      dp[j][i] = max;
    }
  }
  return dp[0][n - 1];
}


public static class AngleCompare implements Comparator<Point> {

  @Override
  public int compare(Point o1, Point o2) {
    if (o1.x >= 0 && o2.x >= 0) {
      return o1.y < o2.y ? -1 : 1;
    } else if (o1.x < 0 && o2.x < 0) {
      return o2.y < o1.y ? -1 : 1;
    } else {
      return o1.x < o2.x ? 1 : -1;
    }
  }

}

public static int MaxSetPoints(Point[][] segments){

  Point[] array = new Point[segments.length * 2];
  for (int i = 0; i < segments.length; i++) {
    array[i * 2] = segments[i][0];
    array[i * 2 + 1] = segments[i][1];
  }
  HashMap<Point, Integer> order = new HashMap<>();

// Sort points by clock-wise order
// Comparison function not using any sin,cos function which is slow

  Arrays.sort(array, new AngleCompare());
  for (int i = 0; i < array.length; i++) {
    order.put(array[i], i);
  }

// Flatten into integer array, 
// Non zero elements indicates start point, value is the end point
// Negative value is an end point

  int[] segs = new int[segments.length * 2];
  for (Point[] si : segments) {
    segs[order.get(si[0])] = order.get(si[1]);
    segs[order.get(si[1])] = -1;
  }
  return MaxSetDP(segs);
}

- guruqu November 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You said DP(i,j) = argmax_k (1+DP(k_start+1,k_end-1)+DP(k_end+1,j))
Why don't you add DP(i,k_start - 1) to this sum?

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

Anyway if I understand you right and DP(i,j) is max number of line segments which endpoints are between i and j (endpoints are sorted by angle) then there is another recursion:
DP(i,j) = max(DP(i,j-1), DP(i+1,j), line + DP(i+1,j-1)), where line is 1 if there is a line segment with endpoints in (i,j), 0 if there is no such line segment.
It seems to give O(n^2) in time.

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

Your state transition is wrong. Consider
0,5
1,2
3,4

- guruqu November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Wrt. Your first comment.
Since transition is base on first optimal seg in range.
We don't need to add DP(i,kstart-1) this won't change result but making transition graph complicated.

- guruqu November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Solution using DP is correct, and it would be O(N^2) time and space:
DP(i, j) = max(DP(i, j-1), DP(i+1, j), DP(i-1, j-1)+line(i,j))

- gen-y-s November 03, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Does it pass this test case?
1,2
3,4
Since that DP transition will give answer of 1 instead of correct answer 2.

- guruqu November 03, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

DP(i,j)= max( DP(i, i+k)+ line(i,i+k) + DP(i+k, j) + line(i+k, j)) for eack k in 0..j-i

- gen-y-s November 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The recursive formula, which can be computed using dynamic programming:

S[i, j] = line[i, j] + max( S[i, k] + S[k, j]) for each k=i+1...j-1

where line[i, j] = 1 if there is a line from point i to point j, otherwise 0

computing this will take O(N^3) and use O(N^2) space, since we need to compute the matrix S which contains N^2 values, and each cell computation would take O(N) time since we need to apply max on up to N values.

- gen-y-s November 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

solution in python:

#!/usr/bin/python

def xline(l):
  def xline_int(i, j):
    if s[i][j]==None:
      v=0
      for k in xrange(i+1, j):
        v=max(v, xline_int(i, k)+xline_int(k, j))
      s[i][j]=v+m[i][j]
    return s[i][j]

  n=len(l)
  m=[[0 for i in xrange(2*n)] for j in xrange(2*n)]
  for x in l:
    m[min(x[0], x[1])][max(x[0], x[1])] = 1

  s=[[None for i in xrange(2*n)] for j in xrange(2*n)]
  return xline_int(0, 2*n-1)

def main():
  l=[(0,5), (1,2), (3,4)]
  print l
  print xline(l)
  print "=========="

if __name__ == "__main__":
  main()

- gen-y-s November 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks for your nice solution and code !!!

- yzl232 November 08, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Not sure if this works (especially since it's quite simple), so let me know if you can find a counter-example.
(1) For each segment, count how many times it intersects with the other segments - O(n^2)
(2) Sort the segments by their number of intersections - O(nlogn)
(3) Iterate through the segments and include each segment as long as it doesn't intersect any of the current ones - O(n)

So O(n^2) total.

- Sunny November 02, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This example would be a counter?
tinyurl.com/psnzxtv

- guruqu November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks. Now I don't have to struggle to prove it. Here's another counter-example I found:
(1) A vertical line segment
(2) Another vertical line segment
(3) A horizontal line segment that intersects both (1) & (2)
(4) Another horizontal line segment that intersects both (1) & (2)
(5) A line segment that intersects (1)

In this case, the optimal solution would be (5), (3), (4) but my algorithm would probably have returned (5), (2).

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

:)

- guruqu November 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I think your answer is close.
My step 3 was different:
(3) Iterate through the segments (from segments with most intersections to fewest) and remove them until there are no longer any intersections.

- Aron November 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

With the same 5-segments example I had above, these are how many intersections each segment has:
(1) 3 intersections
(2) 2 intersections
(3) 2 intersections
(4) 2 intersections
(5) 1 intersection

With your approach, we would first remove (1). Then depending on the ordering, we might remove (3) & (4), thus ending up with (5) & (2), as opposed to the optimal solution of (5), (3), (4).

- Sunny November 05, 2014 | Flag


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