WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Dynamic Programming · Guru · question 85 of 100

How can dynamic programming be applied to solve the Discrete Convex Hull problem? Implement the solution.?

📕 Buy this interview preparation book: 100 Dynamic Programming questions & answers — PDF + EPUB for $5

The discrete convex hull problem can be defined as finding the smallest convex polygon that encloses a set of discrete points in the Euclidean plane. In this problem, we will be using dynamic programming to solve for the convex hull.

The basic idea of dynamic programming is to divide a problem into smaller subproblems and then solve each subproblem only once by storing its solution. Then, we can use the stored solution to solve larger subproblems.

In this case, we can use dynamic programming to solve the discrete convex hull problem by breaking it down into smaller subproblems. We can do this by considering all possible subsets of the points and finding the smallest convex polygon that encloses each subset. Then, we can use the solutions to the smaller subproblems to construct the solution to the entire problem.

For each subset of points, we can find the smallest convex polygon that encloses the subset by first finding the leftmost and rightmost points in the subset. Then, we can split the subset into two parts, one to the left of a line connecting the leftmost and rightmost points and one to the right. We can then recursively find the smallest convex polygons that enclose the two parts and combine them to form the smallest convex polygon that encloses the entire subset.

Here’s the Java implementation of the algorithm:

import java.util.*;

public class DiscreteConvexHull {

    private static List<Point> convexHull(List<Point> points) {
        Map<Set<Point>, List<Point>> cache = new HashMap<>();
        return convexHull(points, cache);
    }

    private static List<Point> convexHull(List<Point> points, Map<Set<Point>, List<Point>> cache) {
        if (points.size() <= 2) {
            return points;
        }
        Set<Point> set = new HashSet<>(points);
        if (cache.containsKey(set)) {
            return cache.get(set);
        }
        List<Point> hull = new ArrayList<>();
        Point leftmost = leftmostPoint(points);
        Point rightmost = rightmostPoint(points);
        List<Point> left = new ArrayList<>();
        List<Point> right = new ArrayList<>();
        for (Point point : points) {
            if (point == leftmost || point == rightmost) {
                continue;
            }
            if (orientation(leftmost, rightmost, point) < 0) {
                left.add(point);
            } else if (orientation(leftmost, rightmost, point) > 0) {
                right.add(point);
            }
        }
        hull.add(leftmost);
        hull.addAll(convexHull(left, cache));
        hull.add(rightmost);
        hull.addAll(convexHull(right, cache));
        cache.put(set, hull);
        return hull;
    }

    private static Point leftmostPoint(List<Point> points) {
        Point leftmost = points.get(0);
        for (Point point : points) {
            if (point.x < leftmost.x) {
                leftmost = point;
            }
        }
        return leftmost;
    }

    private static Point rightmostPoint(List<Point> points) {
        Point rightmost = points.get(0);
        for (Point point : points) {
            if (point.x > rightmost.x) {
                rightmost = point;
            }
        }
        return rightmost;
    }

    private static int orientation(Point p1, Point p2, Point p3) {
        int val = (p2.y - p1.y) * (p3.x - p2.x) - (p2.x - p1.x) * (p3.y - p2.y);
        if (val == 0) {
            return 0;
        } else if (val > 0) {
            return 1;
        } else {
            return -1;
        }
    }

    public static void main(String[] args) {
        List<Point> points = new ArrayList<>();
        points.add(new Point(0, 0));
        points.add(new Point(1, 0));
        points.add(new Point(2, 1));
        points.add(new Point(1, 2));
        points.add(new Point(0, 2));
        List<Point> hull = convexHull(points);
        System.out.println(hull); // [(0, 0), (2, 1), (1, 2), (0, 2)]
    }

    static class Point {
        int x;
        int y;

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

        @Override
        public String toString() {
            return "(" + x + ", " + y + ")";
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Point point = (Point) o;
            return x == point.x &&
                    y == point.y;
        }

        @Override
        public int hashCode() {
            return Objects.hash(x, y);
        }
    }
}

In this implementation, we use a map called ‘cache‘ to store the solutions to the subproblems so that we don’t have to repeat the calculations. We also define a ‘Point‘ class to represent points in the Euclidean plane.

The ‘convexHull‘ method is the main dynamic programming algorithm. It first checks if the set of points has already been solved by looking it up in the ‘cache‘. If it has, it returns the stored solution. Otherwise, it finds the leftmost and rightmost points in the set and splits the set into two parts based on a line connecting the leftmost and rightmost points. It then recursively finds the convex hulls of the two parts and combines them to form the convex hull of the original set.

The ‘leftmostPoint‘ and ‘rightmostPoint‘ methods simply find the leftmost and rightmost points in a set of points. The ‘orientation‘ method calculates the orientation of three points using the cross product.

In the ‘main‘ method, we create a set of points and find its convex hull using the ‘convexHull‘ method.

For example, if we have the set of points ‘[(0, 0), (1, 0), (2, 1), (1, 2), (0, 2)]‘, the output will be ‘[(0, 0), (2, 1), (1, 2), (0, 2)]‘, which is the smallest convex polygon that encloses the set of points.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Dynamic Programming interview — then scores it.
📞 Practice Dynamic Programming — free 15 min
📕 Buy this interview preparation book: 100 Dynamic Programming questions & answers — PDF + EPUB for $5

All 100 Dynamic Programming questions · All topics