587. 安装栅栏

在一个二维的花园中,有一些用 (x, y) 坐标表示的树。由于安装费用十分昂贵,你的任务是先用最短的绳子围起所有的树。只有当所有的树都被绳子包围时,花园才能围好栅栏。你需要找到正好位于栅栏边界上的树的坐标。

示例 1:

输入: [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]]

输出: [[1,1],[2,0],[4,2],[3,3],[2,4]]

解释:



示例 2:

输入: [[1,2],[2,2],[4,2]]

输出: [[1,2],[2,2],[4,2]]

解释:



即使树都在一条直线上,你也需要先用绳子包围它们。

注意:

所有的树应当被围在一起。你不能剪断绳子来包围树或者把树分成一组以上。

输入的整数在 0 到 100 之间。

花园至少有一棵树。

所有树的坐标都是不同的。

输入的点没有顺序。输出顺序也没有要求。

class Solution {
public int[][] outerTrees(int[][] points) {
Set<int[]> hull = new HashSet<>(); // 如果树的棵数小于 4 ,那么直接返回
if (points.length < 4) {
for (int[] p : points) hull.add(p);
return hull.toArray(new int[hull.size()][]);
} // 找到最左边的点
int leftMost = 0;
for (int i = 0; i < points.length; i++) {
if (points[i][0] < points[leftMost][0]) leftMost = i;
} int p = leftMost;
do {
int q = (p + 1) % points.length; for (int i = 0; i < points.length; i++) {
// 如果 i 点在 pq 线下方,则使用 i 点
if (orientation(points[p], points[i], points[q]) < 0) q = i;
}
for (int i = 0; i < points.length; i++) {
// p、q、i 在同一条线上的情况,并且 i 在 p 和 q 的中间的时候
// 也需要将这个点算进来
if (i != p && i != q
&& orientation(points[p], points[i], points[q]) == 0
&& inBetween(points[p], points[i], points[q])) {
hull.add(points[i]);
}
} hull.add(points[q]);
// 重置 p 为 q,接着下一轮的遍历
p = q;
} while (p != leftMost); return hull.toArray(new int[hull.size()][]);
} // 以下 pq 和 qr 都是向量
// pq * qr > 0 表示 r 点在 pq 线上方
// pq * qr < 0 表示 r 点在 pq 线下方
// pq * qr = 0 表示 p、q、r 一条线
// |(q[0]-p[0]) (q[1]-p[1])|
// pq * qr = | | = (q[0]-p[0]) * (r[1]-q[1]) - (r[0]-q[0]) * (q[1]-p[1])
// |(r[0]-q[0]) (r[1]-q[1])|
private int orientation(int[] p, int[] r, int[] q) {
return (q[0] - p[0]) * (r[1] - q[1]) - (r[0] - q[0]) * (q[1] - p[1]);
} // 判断 r 点是不是在 p 点和 q 点之间,需要考虑以下两种情况:
// 1. q 点在 p 点的左边或者右边
// 2. q 点在 p 点的上边或者下边
private boolean inBetween(int[] p, int[] r, int[] q) {
boolean a = r[0] >= p[0] && r[0] <= q[0] || r[0] <= p[0] && r[0] >= q[0];
boolean b = r[1] >= p[1] && r[1] <= q[1] || r[1] <= p[1] && r[1] >= q[1];
return a && b;
}
}

Java实现 LeetCode 587 安装栅栏(图算法转换成数学问题)的更多相关文章

  1. Leetcode 587.安装栅栏

    安装栅栏 在一个二维的花园中,有一些用 (x, y) 坐标表示的树.由于安装费用十分昂贵,你的任务是先用最短的绳子围起所有的树.只有当所有的树都被绳子包围时,花园才能围好栅栏.你需要找到正好位于栅栏边 ...

  2. 分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map

    原文:分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map import java.util.Map; import org.apache.commons.lang.Ar ...

  3. LeetCode 709. To Lower Case (转换成小写字母)

    题目标签:String 题目让我们把大写字母转换成小写,只要遇到的是大写字母,把它 + 32 变成 小写就可以了. Java Solution: Runtime beats 100.00% 完成日期: ...

  4. 【LeetCode】To Lower Case(转换成小写字母)

    这道题是LeetCode里的第709道题. 题目要求: 实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串. 示例 1: ...

  5. Java中将0x开头的十六进制字符串转换成十进制整数

    1.Integer.toString(int i) 由于input(输入数据)是以0x开头的字符串,并不是整型.因而在用 String s = Integer.toString(input); 时用会 ...

  6. java算法:统计数字-将数字转换成字符串,然后使用字符串String.valueOf()方法进行判断

    题目: 计算数字 k 在 0 到 n 中的出现的次数,k 可能是 0~9 的一个值. 样例 样例 1: 输入: k = 1, n = 1 输出: 1 解释: 在 [0, 1] 中,我们发现 1 出现了 ...

  7. java调用com组件将office文件转换成pdf

    在非常多企业级应用中都涉及到将office图片转换成pdf进行保存或者公布的场景,由于pdf格式的文档方便进行加密和权限控制(类似于百度文库).总结起来眼下将office文件转换 成pdf的方法主要有 ...

  8. Java实现 LeetCode 552 学生出勤记录 II(数学转换?还是动态规划?)

    552. 学生出勤记录 II 给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值. 学生出勤记录是只包含以下三个字符的 ...

  9. java泛型基础、子类泛型不能转换成父类泛型

    参考http://how2j.cn/k/generic/generic-generic/373.html 1.使用泛型的好处:泛型的用法是在容器后面添加<Type>Type可以是类,抽象类 ...

随机推荐

  1. 【Kafka】Producer API

    Producer API Kafka官网文档给了基本格式 地址:http://kafka.apachecn.org/10/javadoc/index.html?org/apache/kafka/cli ...

  2. 【Hadoop离线基础总结】通过Java代码执行Shell命令

    通过Java代码执行Shell命令 需求 在实际工作中,总会有些时候需要我们通过java代码通过远程连接去linux服务器上面执行一些shell命令,包括一些集群的状态管理,执行任务,集群的可视化界面 ...

  3. HDU-6351 Beautiful Now 全排列暴力

    Beautiful Now 题意 给出一个最大为10^9的数字n,以及一个k,你最多交换n中任意两个位置的数字k次,问形成的最大数字和最小数字. 思路 看到这题,我靠这题暴力交换一下,不难啊,咋没人做 ...

  4. .NETcore中使用jwt来对api进行身份验证

    对于 登陆,身份,授权这之类的操作,我们最常用的几种方法无非就是 cookie session token 这三者的差别 https://www.cnblogs.com/moyand/p/904797 ...

  5. 嫌弃Apriori算法太慢?使用FP-growth算法让你的数据挖掘快到飞起

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第20篇文章,我们来看看FP-growth算法. 这个算法挺冷门的,至少比Apriori算法冷门.很多数据挖掘的教材还会 ...

  6. 关于layui数据表格的各种事件

    table.on('tool(demo)', function(obj){}):监听工具条事件,tool 是工具条事件名,demo 是 table 原始容器的属性 lay-filter="对 ...

  7. Codeforces Round #643 (Div.2)

    前言:这套cf我感觉出的很不错,AB就不说了,唯一有点欠缺的就是C和D的位置应该换一下,C出的挺不错,反正我当时没有想出来(赛后补题的时候其实也不难..听朋友说还可以FFT优化,然而我是个图论手并不会 ...

  8. 1026 Table Tennis (30分) 难度不高 + 逻辑复杂 +细节繁琐

    题目 A table tennis club has N tables available to the public. The tables are numbered from 1 to N. Fo ...

  9. 使用naxsi

    naxsi简介 naxsi 是一个nginx 防病毒,防跨站,sql 注入的一个模块.nginx的一个waf ,应用防火墙.非常好配置. naxsi 安装 naxsi 在debina/ubuntu 上 ...

  10. spark机器学习从0到1基本数据类型之(二)

        MLlib支持存储在单个机器上的局部向量和矩阵,以及由一个或多个RDD支持的分布式矩阵. 局部向量和局部矩阵是用作公共接口的简单数据模型. 底层线性代数操作由Breeze提供. 在监督学习中使 ...