难度等级:困难
题目描述:
给定两条线段(表示为起点start = {X1, Y1}
和终点end = {X2, Y2}
),如果它们有交点,请计算其交点,没有交点则返回空值。
要求浮点型误差不超过10^-6
。若有多个交点(线段重叠)则返回 X 值最小的点,X 坐标相同则返回 Y 值最小的点。
示例 1:
输入: line1 = {0, 0}, {1, 0} line2 = {1, 1}, {0, -1} 输出: {0.5, 0}
示例 2:
输入: line1 = {0, 0}, {3, 3} line2 = {1, 1}, {2, 2} 输出: {1, 1}
示例 3:
输入: line1 = {0, 0}, {1, 1} line2 = {1, 0}, {2, 1} 输出: {},两条线段没有交点
提示:
- 坐标绝对值不会超过 2^7
- 输入的坐标均是有效的二维坐标
解题思路:
思路一:通过多项式求解线条交点。注意垂直线条的情况。
思路二:使用二分法遍历求解,链接:https://leetcode-cn.com/problems/intersection-lcci/solution/py3er-fen-cha-zhao-fa-si-lu-lai-yuan-yu-zuo-tian-d/
解题代码:
本人使用思路一:
class Solution: def intersection(self, start1: List[int], end1: List[int], start2: List[int], end2: List[int]) -> List[float]: orig_x1 = [min(start1[0], end1[0]), max(start1[0], end1[0])] # line1的x取值范围 orig_x2 = [min(start2[0], end2[0]), max(start2[0], end2[0])] # line2的x取值范围 final_x = [max(orig_x1[0], orig_x2[0]), min(orig_x1[1], orig_x2[1])] # 两条线x合并后的取值范围,若final_x[0] > final_x[1],表示两条线x无交集,线条不会有交点 orig_y1 = [min(start1[1], end1[1]), max(start1[1], end1[1])] orig_y2 = [min(start2[1], end2[1]), max(start2[1], end2[1])] final_y = [max(orig_y1[0], orig_y2[0]), min(orig_y1[1], orig_y2[1])] # line1垂直,line2不垂直 if start1[0]==end1[0] and start2[0]!=end2[0]: x = start1[0] y = (end2[1] - start2[1]) * (x - start2[0]) / (end2[0] - start2[0]) + start2[1] rt = [x, y] # line2垂直,line1不垂直 elif start1[0]!=end1[0] and start2[0]==end2[0]: x = start2[0] y = (end1[1] - start1[1]) * (x - start1[0]) / (end1[0] - start1[0]) + start1[1] rt = [x, y] # line1,line2都垂直 elif start1[0]==end1[0] and start2[0]==end2[0]: # 如果两条都是垂线 if start1[0] != start2[0]: # 若两条线不重合 rt = [] else: # 若两条线断重合,判断是否有交集。 x = start1[0] if final_y[0] <= final_y[1]: rt = [float(x), float(final_y[0])] else: rt = [] # line1, line2都不垂直 else: a1 = (start1[1] - end1[1]) / (start1[0] - end1[0]) b1 = start1[1] - a1 * start1[0] a2 = (start2[1] - end2[1]) / (start2[0] - end2[0]) b2 = start2[1] - a2 * start2[0] if a1 != a2: # 线段斜率不相等 x = (b2 - b1) / (a1 - a2) y = a1 * x + b1 if x >= final_x[0] and x <= final_x[1]: # 判断题解是否在线段内 rt = [float(x), float(y)] else: rt = [] else: # 线段斜率相等 if b1==b2: # 如果线段重叠,取x最小的点。若x最小点相同,则返回y值最小的点 if final_x[0] <= final_x[1]: x = final_x[0] y = a1 * x + b1 rt = [x, y] else: rt = [] else: rt = [] return rt