|
50鱼币
本帖最后由 zltzlt 于 2020-4-16 12:53 编辑
今天的题目:
在一个二维的花园中,有一些用 (x, y) 坐标表示的树。
由于安装费用十分昂贵,所以要先用最短的绳子围起所有的树。
只有当所有的树都被绳子包围时,花园才能围好栅栏。找到正好位于栅栏边界上的树的坐标。
说明:
1. 输入的点没有顺序,输出的点也没有顺序要求。
2. 所有的树应当被围在一起,不能剪断绳子来包围树或者把树分成一组以上。
3. 花园至少有一棵树。
4. 所有树的坐标都是不同的。
示例 1:
输入:[[1, 1], [2, 2], [2, 0], [2, 4], [3, 3], [4, 2]]
输出:[[1, 1], [2, 0], [4, 2], [2, 4], [3, 3]]
解释:
示例 2:
输入:[[1, 2], [2, 2], [4, 2]]
输出:[[1, 2], [2, 2], [4, 2]]
解释:
即使树都在一条直线上,也需要先用绳子包围它们。
 欢迎大家一起答题! 
本帖最后由 March2615 于 2020-4-16 15:59 编辑
- # 解题思路:
- # 从最左边一棵树开始,逆时针绕着围
- # 如果是逆时针转,则向量叉乘为正,否则,叉乘为负(可以想象成应该一直左转不能有右转)
- # 叉乘要三个点,所以不足两个点的时候不管是不是为正,都要认为是边界上的
- def daily377(trees: list) -> list:
- if len(trees) < 4: # 小于四棵树的时候,肯定都在边界上了
- return trees
- def cross(p1, p2, p3): # p1->p2 & p2->p3
- return (p1[0] - p2[0]) * (p3[1] - p2[1]) - (p1[1] - p2[1]) * (p3[0] - p2[0])
- down = []
- for tree in sorted(trees):
- while len(down) >= 2 and cross(down[-2], down[-1], tree) < 0:
- down.pop()
- down.append(tree)
- up = []
- for tree in sorted(trees, reverse=True):
- while len(up) >= 2 and cross(up[-2], up[-1], tree) < 0:
- up.pop()
- up.append(tree)
- result = []
- for each in down[:-1] + up[:-1]:
- if each not in result:
- result.append(each)
- return result
复制代码
不知不觉一下午过去了
|
|