Java实现 LeetCode 587 安装栅栏(图算法转换成数学问题)
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 安装栅栏(图算法转换成数学问题)的更多相关文章
- Leetcode 587.安装栅栏
安装栅栏 在一个二维的花园中,有一些用 (x, y) 坐标表示的树.由于安装费用十分昂贵,你的任务是先用最短的绳子围起所有的树.只有当所有的树都被绳子包围时,花园才能围好栅栏.你需要找到正好位于栅栏边 ...
- 分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map
原文:分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map import java.util.Map; import org.apache.commons.lang.Ar ...
- LeetCode 709. To Lower Case (转换成小写字母)
题目标签:String 题目让我们把大写字母转换成小写,只要遇到的是大写字母,把它 + 32 变成 小写就可以了. Java Solution: Runtime beats 100.00% 完成日期: ...
- 【LeetCode】To Lower Case(转换成小写字母)
这道题是LeetCode里的第709道题. 题目要求: 实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串. 示例 1: ...
- Java中将0x开头的十六进制字符串转换成十进制整数
1.Integer.toString(int i) 由于input(输入数据)是以0x开头的字符串,并不是整型.因而在用 String s = Integer.toString(input); 时用会 ...
- java算法:统计数字-将数字转换成字符串,然后使用字符串String.valueOf()方法进行判断
题目: 计算数字 k 在 0 到 n 中的出现的次数,k 可能是 0~9 的一个值. 样例 样例 1: 输入: k = 1, n = 1 输出: 1 解释: 在 [0, 1] 中,我们发现 1 出现了 ...
- java调用com组件将office文件转换成pdf
在非常多企业级应用中都涉及到将office图片转换成pdf进行保存或者公布的场景,由于pdf格式的文档方便进行加密和权限控制(类似于百度文库).总结起来眼下将office文件转换 成pdf的方法主要有 ...
- Java实现 LeetCode 552 学生出勤记录 II(数学转换?还是动态规划?)
552. 学生出勤记录 II 给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值. 学生出勤记录是只包含以下三个字符的 ...
- java泛型基础、子类泛型不能转换成父类泛型
参考http://how2j.cn/k/generic/generic-generic/373.html 1.使用泛型的好处:泛型的用法是在容器后面添加<Type>Type可以是类,抽象类 ...
随机推荐
- ActiveMQ 事务、集群、持久订阅者、ActiveMQ监控
JMS介绍 JMS是什么? JMS的全称Java Message Service,既Java消息服务. JMS是SUN提供的旨在统一各种MOM(Message-Oriented Middleware) ...
- ubuntu安装java方法
详情请点链接:https://www.digitalocean.com/community/tutorials/how-to-install-java-with-apt-get-on-ubuntu-1 ...
- 新鲜出炉高仿网易云音乐 APP
我的引语 晚上好,我是吴小龙同学,我的公众号「一分钟GitHub」会推荐 GitHub 上好玩的项目,一分钟 get 一个优秀的开源项目,挖掘开源的价值,欢迎关注我. 项目中成长是最快的,如何成长,就 ...
- java ->IO流_序列化流与反序列化流
序列化流与反序列化流 用于从流中读取对象的操作流 ObjectInputStream 称为 反序列化流 用于向流中写入对象的操作流 ObjectOutputStream 称为 序列化流(对象 ...
- 基于Redis的Nginx服务器集群session共享
原料:jdk1.8,tomcat7,nginx1.16,Redis3.2.100,Redis-Tomcat需要的jar包,基于windows7. Redis3.2.100与Redis-Tomcat需要 ...
- 修改jupyter默认保存文件的目录
1.打开 Anaconda Prompt输入命令 jupyter notebook --generate-config 2.可以看到生成了目录及jupyter notebook的配置文件,打开该文件. ...
- 我的.emacs配置
我不是大神,使用vim和emacs只是兴趣,打发空闲时间. 上代码: ;; Added by Package.el. This must come before configurations of ; ...
- jmeter学习之安装篇(一)
一.Jmeter简介 Jmeter是Apache组织开发的基于Java开源项目,设计之初是用于做性能测试的,同时它在实现对各种接口的调用方面做的比较成熟,因此,常被用做接口功能测试和性能测试. Jme ...
- 笨办法学习python之hashmap
#!/user/bin/env python #-*-coding:utf-8 -*- #Author: qinjiaxi #初始化aMap列表,把列表num_buckets添加到aMap中,num_ ...
- Django之ORM对象关系模型
MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需 ...