587. Erect the Fence

Il testo del problema è tradotto dal russo per la lingua selezionata. Il codice resta invariato.

Вам дан array trees, где trees[i] = [xi, yi] представляет местоположение дерева в саду.

Оградите весь сад с использованием минимальной длины веревки, так как это дорого. Сад хорошо огорожен только в том случае, если все деревья окружены.

return координаты деревьев, которые находятся точно на периметре ограды. Вы можете вернуть ответ в любом порядке.

Esempio:

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# soluzione

abbinato/originale
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++ soluzione

bozza automatica, rivedere prima dell'invio
#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 soluzione

abbinato/originale
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 soluzione

abbinato/originale
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 soluzione

abbinato/originale
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 soluzione

abbinato/originale
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, чтобы удалить дублирующиеся точки из стека.

Преобразуйте результат в array и return его.

😎

Vacancies for this task

offerte attive with overlapping task tags are mostrati.

Tutte le offerte
Non ci sono ancora offerte attive.