Just
**[[currentUser.getNumFreeQuestionsLeft()]]**
No
more free questions
left!

**
A crack team of love scientists from OkEros (a hot new dating site) have devised a way to represent dating profiles as rectangles on a two-dimensional plane.
**

**They need help writing an algorithm to find the intersection of two users' love rectangles.** They suspect finding that intersection is the key to a matching algorithm *so powerful* it will cause an immediate acquisition by Google or Facebook or Obama or something.

**Write a function to find the rectangular intersection of two given love rectangles.**

As with the example above, love rectangles are always "straight" and never "diagonal." More rigorously: each side is parallel with either the x-axis or the y-axis.

They are defined as objects of Rectangle class:

public class Rectangle {
// coordinates of bottom left corner
Integer leftX;
Integer bottomY;
// dimensions
Integer width;
Integer height;
public Rectangle(Integer leftX, Integer bottomY, Integer width, Integer height) {
this.leftX = leftX;
this.bottomY = bottomY;
this.width = width;
this.height = height;
}
public Rectangle() {}
public String toString() {
return String.format("(%d, %d, %d, %d)", leftX, bottomY, width, height);
}
}

Your output rectangle should be a Rectangle object as well.

**What if there is no intersection?** Does your function do something reasonable in that case?

**What if one rectangle is entirely contained in the other?** Does your function do something reasonable in that case?

**What if the rectangles don't really intersect but share an edge?** Does your function do something reasonable in that case?

Do some parts of your function seem very similar? Can they be refactored so you repeat yourself less?

Let's break this problem into subproblems. How can we divide this problem into smaller parts?

We could look at the two rectangles’ "horizontal overlap" or "x overlap" separately from their "vertical overlap" or "y overlap."

**
Lets start with a helper function findXOverlap.
**

Need help finding the x overlap?

Since we’re only working with the x dimension, we can treat the two rectangles' widths as ranges on a 1-dimensional number line.

What are the possible cases for how these ranges might overlap or not overlap? Draw out some examples!

**
There are four relevant cases:
**

1) The ranges partially overlap:

2) One range is completely contained in the other:

3) The ranges don't overlap:

4) The ranges "touch" at a single point:

Let's start with the first 2 cases. **How do we compute the overlapping range?**

One of our ranges starts "further to the right" than the other. We don't know ahead of time which one it is, but we can check the starting points of each range to see which one has the highestStartPoint. **That highestStartPoint is always the left-hand side of the overlap**, if there is one.

Not convinced? Draw some examples!

Similarly, **the right-hand side of our overlap is always the lowestEndPoint**. That *may or may not* be the end point of the same input range that had the highestStartPoint—compare cases (1) and (2).

This gives us our x overlap! So we can handle cases (1) and (2). **How do we know when there is no overlap?**

If highestStartPoint > lowestEndPoint, the two rectangles do not overlap.

But be careful—is it just *greater than* or is it *greater than or equal to*?

It depends how we want to handle case (4) above.

If we use *greater than*, we treat case (4) as an overlap. This means we could end up returning a rectangle with *zero width*, which ... may or may not be what we're looking for. You could make an argument either way.

Let's say a rectangle with zero width (or zero height) isn't a rectangle at all, so we should treat that case as "no intersection."

**
Can you finish findXOverlap?
**

Here's one way to do it:

public class XOverlap {
Integer startPoint;
Integer width;
public XOverlap(Integer startPoint, Integer width) {
this.startPoint = startPoint;
this.width = width;
}
}
public XOverlap findXOverlap(int x1, int width1, int x2, int width2) {
// find the highest ("rightmost") start point and lowest ("leftmost") end point
int highestStartPoint = Math.max(x1, x2);
int lowestEndPoint = Math.min(x1 + width1, x2 + width2);
// return null overlap if there is no overlap
if (highestStartPoint >= lowestEndPoint) {
return new XOverlap(null, null);
}
// compute the overlap width
int overlapWidth = lowestEndPoint - highestStartPoint;
return new XOverlap(highestStartPoint, overlapWidth);
}

**
How can we adapt this for the rectangles’ ys and heights?
**

Can we just make one findRangeOverlap function that can handle x overlap and y overlap?

Yes! We simply use more general parameter names:

public class RangeOverlap {
Integer startPoint;
Integer length;
public RangeOverlap(Integer highestStartPoint, Integer overlapLength) {
this.startPoint = highestStartPoint;
this.length = overlapLength;
}
}
public RangeOverlap findRangeOverlap(int point1, int length1, int point2, int length2) {
// find the highest start point and lowest end point.
// the highest ("rightmost" or "upmost") start point is
// the start point of the overlap.
// the lowest end point is the end point of the overlap.
int highestStartPoint = Math.max(point1, point2);
int lowestEndPoint = Math.min(point1 + length1, point2 + length2);
// return null overlap if there is no overlap
if (highestStartPoint >= lowestEndPoint) {
return new RangeOverlap(null, null);
}
// compute the overlap length
int overlapLength = lowestEndPoint - highestStartPoint;
return new RangeOverlap(highestStartPoint, overlapLength);
}

We've solved our subproblem of finding the x and y overlaps! **Now we just need to put the results together.**

We divide the problem into two halves:

- The intersection along the x-axis
- The intersection along the y-axis

Both problems are basically the same as finding the intersection of two "ranges" on a 1-dimensional number line.

So we write a helper function findRangeOverlap that can be used to find both the x overlap and the y overlap, and we use it to build the rectangular overlap:

public class RangeOverlap {
Integer startPoint;
Integer length;
public RangeOverlap(Integer startPoint, Integer length) {
this.startPoint = startPoint;
this.length = length;
}
}
public RangeOverlap findRangeOverlap(int point1, int length1, int point2, int length2) {
// find the highest start point and lowest end point.
// the highest ("rightmost" or "upmost") start point is
// the start point of the overlap.
// the lowest end point is the end point of the overlap.
int highestStartPoint = Math.max(point1, point2);
int lowestEndPoint = Math.min(point1 + length1, point2 + length2);
// return null overlap if there is no overlap
if (highestStartPoint >= lowestEndPoint) {
return new RangeOverlap(null, null);
}
// compute the overlap length
int overlapLength = lowestEndPoint - highestStartPoint;
return new RangeOverlap(highestStartPoint, overlapLength);
}
public Rectangle findRectangularOverlap(Rectangle rect1, Rectangle rect2) {
// get the x and y overlap points and lengths
RangeOverlap xOverlap = findRangeOverlap(rect1.leftX, rect1.width, rect2.leftX, rect2.width);
RangeOverlap yOverlap = findRangeOverlap(rect1.bottomY, rect1.height, rect2.bottomY, rect2.height);
// return null rectangle if there is no overlap
if (xOverlap.length == null || yOverlap.length == null) {
return new Rectangle();
}
return new Rectangle(
xOverlap.startPoint,
yOverlap.startPoint,
xOverlap.length,
yOverlap.length
);
}

time and space.

What if we had an array of rectangles and wanted to find *all* the rectangular overlaps between all possible pairs of two rectangles within the array? Note that we'd be returning *an array of rectangles*.

What if we had an array of rectangles and wanted to find the overlap between *all* of them, if there was one? Note that we'd be returning *a single rectangle*.

This is an interesting one because the hard part isn't the time or space optimization—it's getting something that *works* and is *readable*.

For problems like this, I often see candidates who can describe the strategy at a high level but trip over themselves when they get into the details.

Don't let it happen to you. To keep your thoughts clear and avoid bugs, take time to:

- Think up and draw out all the possible cases. Like we did with the ways ranges can overlap.
- Use very specific and descriptive variable names.

Code execution powered by Qualified.io

{"id":4886932,"username":"2017-04-27_09:07:12_-)7tzk","email":null,"date_joined":"2017-04-27T09:07:12.700464+00:00","first_name":"","last_name":"","full_name":"","short_name":"friend","is_anonymous":true,"is_on_last_question":false,"percent_done":0,"num_questions_done":0,"num_questions_remaining":44,"recruiting_is_interested_in_intros":null,"is_full_access":false,"first_payment_date":null,"last_payment_date":null,"num_free_questions_left":3,"terms_has_agreed_to_latest":false,"preferred_content_language":"","preferred_notepad_language":"","is_staff":false,"auth_providers_human_readable_list":"","num_auth_providers":0,"auth_email":"","profile_public_id":null}

. . .