587. Erect the Fence
Вам дан 数组 trees, где trees[i] = [xi, yi] представляет местоположение дерева в саду.
Оградите весь сад с использованием минимальной длины веревки, так как это дорого. Сад хорошо огорожен только в том случае, если все деревья окружены.
return координаты деревьев, которые находятся точно на периметре ограды. Вы можете вернуть ответ в любом порядке.
示例:
Input: trees = [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]]
Output: [[1,1],[2,0],[4,2],[3,3],[2,4]]
Explanation: All the trees will be on the perimeter of the fence except the tree at [2, 2], which will be inside the fence.
C# 解法
匹配/原始public 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 IList<IList<int>> OuterTrees(int[][] points) {
Array.Sort(points, (p, q) => p[0] == q[0] ? p[1].CompareTo(q[1]) : p[0].CompareTo(q[0]));
List<int[]> hull = new List<int[]>();
foreach (var point in points) {
while (hull.Count >= 2 && Orientation(hull[hull.Count - 2], hull[hull.Count - 1], point) > 0)
hull.RemoveAt(hull.Count - 1);
hull.Add(point);
}
hull.RemoveAt(hull.Count - 1);
for (int i = points.Length - 1; i >= 0; i--) {
while (hull.Count >= 2 && Orientation(hull[hull.Count - 2], hull[hull.Count - 1], points[i]) > 0)
hull.RemoveAt(hull.Count - 1);
hull.Add(points[i]);
}
HashSet<int[]> ret = new HashSet<int[]>(hull, new ArrayComparer());
return ret.ToList<IList<int>>();
}
private class ArrayComparer : IEqualityComparer<int[]> {
public bool Equals(int[] x, int[] y) {
return x[0] == y[0] && x[1] == y[1];
}
public int GetHashCode(int[] obj) {
return obj[0].GetHashCode() ^ obj[1].GetHashCode();
}
}
}
C++ 解法
自动草稿,提交前请检查#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
public int Orientation(vector<int>& p, vector<int>& q, vector<int>& r) {
return (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);
}
public IList<vector<int>> OuterTrees(int[][] points) {
Array.Sort(points, (p, q) => p[0] == q[0] ? p[1].CompareTo(q[1]) : p[0].CompareTo(q[0]));
List<int[]> hull = new List<int[]>();
foreach (var point in points) {
while (hull.size() >= 2 && Orientation(hull[hull.size() - 2], hull[hull.size() - 1], point) > 0)
hull.RemoveAt(hull.size() - 1);
hull.push_back(point);
}
hull.RemoveAt(hull.size() - 1);
for (int i = points.size() - 1; i >= 0; i--) {
while (hull.size() >= 2 && Orientation(hull[hull.size() - 2], hull[hull.size() - 1], points[i]) > 0)
hull.RemoveAt(hull.size() - 1);
hull.push_back(points[i]);
}
HashSet<int[]> ret = new HashSet<int[]>(hull, new ArrayComparer());
return ret.ToList<vector<int>>();
}
private class ArrayComparer : IEqualityComparer<int[]> {
public bool Equals(vector<int>& x, vector<int>& y) {
return x[0] == y[0] && x[1] == y[1];
}
public int GetHashCode(vector<int>& obj) {
return obj[0].GetHashCode() ^ obj[1].GetHashCode();
}
}
}
Java 解法
匹配/原始public 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, new Comparator<int[]> () {
public int compare(int[] p, int[] q) {
return q[0] - p[0] == 0 ? q[1] - p[1] : q[0] - p[0];
}
});
Stack<int[]> hull = new Stack<>();
for (int i = 0; i < points.length; 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]);
}
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[]> ret = new HashSet<>(hull);
return ret.toArray(new int[ret.size()][]);
}
}
JavaScript 解法
匹配/原始var orientation = function(p, q, r) {
return (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);
};
var outerTrees = function(points) {
points.sort((a, b) => a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
const hull = [];
for (let point of points) {
while (hull.length >= 2 && orientation(hull[hull.length - 2], hull[hull.length - 1], point) > 0) {
hull.pop();
}
hull.push(point);
}
hull.pop();
for (let i = points.length - 1; i >= 0; i--) {
while (hull.length >= 2 && orientation(hull[hull.length - 2], hull[hull.length - 1], points[i]) > 0) {
hull.pop();
}
hull.push(points[i]);
}
const uniqueHull = new Set(hull.map(JSON.stringify));
return Array.from(uniqueHull).map(JSON.parse);
};
Python 解法
匹配/原始class Solution:
def orientation(self, p, q, r):
return (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1])
def outerTrees(self, points):
points.sort(key=lambda x: (x[0], x[1]))
hull = []
for point in points:
while len(hull) >= 2 and self.orientation(hull[-2], hull[-1], point) > 0:
hull.pop()
hull.append(point)
hull.pop()
for point in reversed(points):
while len(hull) >= 2 and self.orientation(hull[-2], hull[-1], point) > 0:
hull.pop()
hull.append(point)
return list(set(map(tuple, hull)))
Go 解法
匹配/原始import "sort"
func orientation(p, q, r []int) int {
return (q[1]-p[1])*(r[0]-q[0]) - (q[0]-p[0])*(r[1]-q[1])
}
func outerTrees(points [][]int) [][]int {
sort.Slice(points, func(i, j int) bool {
if points[i][0] == points[j][0] {
return points[i][1] < points[j][1]
}
return points[i][0] < points[j][0]
})
hull := [][]int{}
for _, point := range points {
for len(hull) >= 2 && orientation(hull[len(hull)-2], hull[len(hull)-1], point) > 0 {
hull = hull[:len(hull)-1]
}
hull = append(hull, point)
}
hull = hull[:len(hull)-1]
for i := len(points) - 1; i >= 0; i-- {
for len(hull) >= 2 && orientation(hull[len(hull)-2], hull[len(hull)-1], points[i]) > 0 {
hull = hull[:len(hull)-1]
}
hull = append(hull, points[i])
}
uniqueHull := make(map[[2]int]bool)
for _, h := range hull {
uniqueHull[[2]int{h[0], h[1]}] = true
}
res := [][]int{}
for k := range uniqueHull {
res = append(res, []int{k[0], k[1]})
}
return res
}
Algorithm
Сортировка точек и построение нижней оболочки:
Отсортируйте точки по их x-координатам, а в случае совпадения x-координат, по y-координатам.
Постройте нижнюю оболочку, добавляя точки к оболочке и удаляя последние точки, если они не образуют против часовой стрелки поворот.
Построение верхней оболочки:
Пройдитесь по точкам в обратном порядке, чтобы построить верхнюю оболочку.
Добавляйте точки к оболочке и удаляйте последние точки, если они не образуют против часовой стрелки поворот.
Удаление дублирующих elementов и возврат результата:
Используйте HashSet, чтобы удалить дублирующиеся точки из стека.
Преобразуйте результат в 数组 и return его.
😎
Vacancies for this task
活跃职位 with overlapping task tags are 已显示.