587.安装栅栏
587.安装栅栏
题解
题目:计算凸包
思路:模板题凸包题,Andrew算法
代码
func outerTrees(trees [][]int) [][]int {
n := len(trees)
if n < 4 {
return trees
}
sort.Slice(trees, func(i, j int) bool {
a, b := trees[i], trees[j]
return a[0] < b[0] || a[0] == b[0] && a[1] < b[1]
})
hull := []int{0}
used := make([]bool, n)
for i := 1; i < n; i++ {
for len(hull) > 1 {
a := trees[hull[len(hull)-2]]
b := trees[hull[len(hull)-1]]
c := trees[i]
if getArea(a, b, c) < 0 {
used[hull[len(hull)-1]] = false
hull = hull[:len(hull)-1]
} else {
break
}
}
used[i] = true
hull = append(hull, i)
}
m := len(hull)
for i := n - 2; i >= 0; i-- {
if !used[i] {
for len(hull) > m {
a := trees[hull[len(hull)-2]]
b := trees[hull[len(hull)-1]]
c := trees[i]
if getArea(a, b, c) < 0 {
used[hull[len(hull)-1]] = false
hull = hull[:len(hull)-1]
} else {
break
}
}
used[i] = true
hull = append(hull, i)
}
}
hull = hull[:len(hull)-1]
ans := make([][]int, len(hull))
for i, idx := range hull {
ans[i] = trees[idx]
}
return ans
}
func subtraction(a, b []int) []int {
return []int{a[0] - b[0], a[1] - b[1]}
}
func cross(a, b []int) int {
return a[0]*b[1] - a[1]*b[0]
}
func getArea(a, b, c []int) int {
return cross(subtraction(b, a), subtraction(c, a))
}
|