Leetcode: 面试题 16.03. 交点

题目

链接:https://leetcode-cn.com/problems/intersection-lcci

给定两条线段(表示为起点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
输入的坐标均是有效的二维坐标

解题记录

  • 优先确定两条线段的定义域
  • 如果两条线段的定义域没有相交部分说明不可能有交点直接返回空
  • 如果定义域满足的话,可以通过求两条线段的延长线,然后求两条直线交点,确定交点是否在定义域内即可
  • 有直线垂直于X轴和直线平行或重合的情况需要进行特殊判断
class Solution {
    public static double[] intersection(int[] start1, int[] end1, int[] start2, int[] end2) {
        int[] line1x = {Math.min(start1[0], end1[0]), Math.max(start1[0], end1[0])};
        int[] line1y = {Math.min(start1[1], end1[1]), Math.max(start1[1], end1[1])};
        int[] line2x = {Math.min(start2[0], end2[0]), Math.max(start2[0], end2[0])};
        int[] line2y = {Math.min(start2[1], end2[1]), Math.max(start2[1], end2[1])};
        double x;
        double y;
        if (line1x[0] > line2x[1] || line2x[0] > line1x[1] || line1y[0] > line2y[1] || line2y[0] > line1y[1]) return new double[]{};
        if ((start1[0]-end1[0]==0) && (start2[0]-end2[0]==0) ){
            return new double[]{(double)start1[0], (double)Math.max(line1y[0], line2y[0])};
        } else if ((start1[0]-end1[0]==0)){
            x = start1[0];
            double k2 = (start2[1]-end2[1])/(double)(start2[0]-end2[0]);
            double b2 = start2[1] - k2*start2[0];
            y = k2*x + b2;
        } else if ((start2[0]-end2[0]==0)){
            x = start2[0];
            double k1 = (start1[1]-end1[1])/(double)(start1[0]-end1[0]);
            double b1 = start1[1] - k1*start1[0];
            y = k1*x + b1;
        } else {
            double k1 = (start1[1]-end1[1])/(double)(start1[0]-end1[0]);
            double k2 = (start2[1]-end2[1])/(double)(start2[0]-end2[0]);
            double b1 = start1[1] - k1*start1[0];
            double b2 = start2[1] - k2*start2[0];
            System.out.println(k1+ ":" + k2);
            if (k1 == k2 ) {
                if (b1 == b2) {
                    x = Math.max(line1x[0], line2x[0]);
                    y = k1*x + b1;
                    return new double[]{x,y};
                }
                return new double[]{};
            }else{
                x = (b2-b1)/(k1-k2);
                y = k1*x + b1;
            }
        }

        if (x>=line1x[0] && x<=line1x[1] && x>=line2x[0] && x<=line2x[1] && y>=line1y[0] && y<=line1y[1] && y>=line2y[0] && y<=line2y[1]){
            return new double[]{x,y};
        }
        return new double[]{};
    }
}

在这里插入图片描述

你可能感兴趣的:(算法)