Given a list of points that form a polygon when joined sequentially, find if this polygon is convex (Convex polygon definition).
Note:
Example 1:
Input: [[0,0],[0,1],[1,1],[1,0]] Output: True Explanation
Example 2:
Input: [[0,0],[0,10],[10,10],[10,0],[5,5]] Output: False Explanation
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
To determine if a shape is a convex polygon using a brute force method, we'll examine every possible combination of three points within the shape. The core idea is to verify that all other points in the shape consistently lie on the same side of each line formed by any two points.
Here's how the algorithm would work step-by-step:
def is_convex_polygon(points):
number_of_points = len(points)
# Need at least 3 points to form a polygon
if number_of_points < 3:
return False
def cross_product(point_a, point_b, point_c):
return (point_b[0] - point_a[0]) * (point_c[1] - point_a[1]) - \
(point_b[1] - point_a[1]) * (point_c[0] - point_a[0])
for i in range(number_of_points):
for j in range(i + 1, number_of_points):
for k in range(j + 1, number_of_points):
# Iterate over the edges of the triangle
for edge_index in range(3):
if edge_index == 0:
point_one = points[i]
point_two = points[j]
elif edge_index == 1:
point_one = points[j]
point_two = points[k]
else:
point_one = points[k]
point_two = points[i]
same_side = True
side = 0
# Check all the other points
for point_index in range(number_of_points):
if point_index != i and point_index != j and point_index != k:
# Determine which side of the line the point is on
cross_product_result = cross_product(point_one, point_two, points[point_index])
if side == 0 and cross_product_result != 0:
side = 1 if cross_product_result > 0 else -1
elif cross_product_result != 0 and \
(1 if cross_product_result > 0 else -1) != side:
# If point is on different side, not convex
same_side = False
break
if not same_side:
return False
return TrueTo check if a shape is a convex polygon, we don't need to check every angle. The trick is to examine the direction of turns we make as we travel around the shape's edges, and see if all the turns go the same way.
Here's how the algorithm would work step-by-step:
def is_convex(points):
number_of_points = len(points)
if number_of_points < 3:
return True
# Determine initial turn direction
turn_direction = 0
for i in range(number_of_points):
point_one = points[i]
point_two = points[(i + 1) % number_of_points]
point_three = points[(i + 2) % number_of_points]
cross_product = (point_two[0] - point_one[0]) * (point_three[1] - point_two[1]) - \
(point_two[1] - point_one[1]) * (point_three[0] - point_two[0])
if cross_product != 0:
turn_direction = cross_product > 0
break
# If all points are co-linear.
if turn_direction == 0:
return True
# Check that all subsequent turns are in the same direction.
for i in range(number_of_points):
point_one = points[i]
point_two = points[(i + 1) % number_of_points]
point_three = points[(i + 2) % number_of_points]
cross_product = (point_two[0] - point_one[0]) * (point_three[1] - point_two[1]) - \
(point_two[1] - point_one[1]) * (point_three[0] - point_two[0])
if cross_product != 0:
current_direction = cross_product > 0
# If turn changes direction, it's not convex
if current_direction != turn_direction:
return False
return True| Case | How to Handle |
|---|---|
| Input is null or an empty array. | Return 'false' or throw an exception indicating invalid input, as a polygon requires at least three points. |
| Input array contains fewer than 3 points. | Return 'false' immediately, as a polygon cannot be formed with fewer than three points. |
| The points are collinear (lie on the same line). | The cross-product will be zero for all triplets; return 'false' since it's not a polygon. |
| The points are in reverse order (clockwise vs counter-clockwise). | The cross-product signs will all be negative, indicating clockwise, so handle consistently. |
| Points are very close together (floating point precision issues). | Use a small epsilon value to compare cross-product results to zero, accounting for floating-point errors. |
| Integer overflow when calculating the cross product with large coordinates. | Use long integers or a similar data type to prevent overflow during cross-product calculations. |
| The polygon is self-intersecting. | The simple cross product method won't work; a more robust algorithm for self-intersection detection is needed. |
| Duplicate points in the input array. | Remove the duplicate points as they do not affect convexity, or handle them as collinear points. |