LeetCode 587. 安装栅栏

这是一个经典的凸包问题,通过对所有点按X坐标排序,然后用栈来构建凸包。算法流程包括遍历点,判断点与栈顶两点形成的夹角,以确定是否入栈。最终栈内的点即为凸包点,复杂度为O(nlogn)。
摘要由CSDN通过智能技术生成

题目链接:安装栅栏

题解标签:凸包

思路:

        经典凸包

        对所有点按X坐标从小到大排序,如果X坐标相同,则按Y坐标从小到大排序。

        使用栈记录形成凸包的点集。

        算法动图如下:

        

        算法流程如下:

                1、以第一个点为基点,从前往后遍历。

                2、当栈中点数小于2时,入栈。

                3、当栈中点数大于等于2时,判断当前点(C)和栈顶两点(A、B)形成的线段AB和BC夹角是否大于180°。①如果大于,则栈顶出栈,重复步骤2、3,②否则当前点入栈。

                4、遍历至最后一个点后,反方向相同逻辑重新遍历直至第一个点。

                5、栈内点去重则得到形成凸包的所有点。

        算法复杂度:排序O(nlogn) + 遍历O(n) = O(nlogn)

代码:

class Solution {
        public int orientation(int[] p, int[] q, int[] r) {
            return (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);
        }

        public int[][] outerTrees(int[][] points) {
            Arrays.sort(points, (p, q) -> q[0] - p[0] == 0 ? q[1] - p[1] : q[0] - p[0]);
            Stack<int[]> hull = new Stack<>();
            for (int[] point : points) {
                while (hull.size() >= 2 && orientation(hull.get(hull.size() - 2), hull.get(hull.size() - 1), point) > 0)
                    hull.pop();
                hull.push(point);
            }
            hull.pop();
            for (int i = points.length - 1; i >= 0; i--) {
                while (hull.size() >= 2 && orientation(hull.get(hull.size() - 2), hull.get(hull.size() - 1), points[i]) > 0)
                    hull.pop();
                hull.push(points[i]);
            }
            HashSet<int[]> set = new HashSet<>(hull);
            return set.toArray(new int[set.size()][2]);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值