LeetCode 面试题16.03 交点

又是暴力破解的一天

而且还是个数学渣

刚看到这一题的时候真的崩溃,稍微列了一下公式后好一点,但又发现按这种解法情况太多

但是自己分的情况跪着也要分完

 

下面先列一下思路:我采用的是最普通的点斜式方程

  • 计算两根直线斜率,判断两根线段的斜率是否存在

    • 都存在
      • 判断是否平行
        • 平行但不重合
          • 此时一定没有交点,返回空数组
        • 重合
          • 判断哪一部分重合并返回题目中所要求的最小点
        • 不平行
          • 计算出两根直线的点斜式方程
          • 计算两根直线交点,并判断交点是否在两根线段范围内
    • 有一根不存在(垂直于x轴)
      • 直线一定重合,但线段不一定重合
      • 计算斜率存在那根直线的点斜式方程
      • 计算直线交点,并判断交点是否在两根线段范围内
    • 两根都不存在(两根都垂直于x轴)
      • 只可能平行或者重合
      • 判断是否重合
        • 重合,则判断哪一部分重合并返回题目中所要求的最小点
        • 平行,返回空数组

 

下面是在提交过程中修改了很多次的代码...

代码能力是挺差劲的,就看看思路吧(也没啥好看的

提交时修改的几个点:

1. 计算k(斜率)时,要先强转成double,否则int类型会出错

2. double类型是存在infinity类型的,所以要判断,直接是抛不出异常的

3. 判断交点是否在线段内时不要忘记等号

最后结果是(我尽力了):

执行用时 :8 ms, 在所有 Java 提交中击败了18.52%的用户

内存消耗 :39 MB, 在所有 Java 提交中击败了100.00%的用户

public static double[] intersection(int[] start1, int[] end1, int[] start2, int[] end2) {
	    //计算k1 k2
		double x_res = 0;
		double y_res = 0;
		
		try {
			//k1 k2均存在
			double k1 = (double)(end1[1] - start1[1])/(double)(end1[0] - start1[0]);
			if(k1 == Double.POSITIVE_INFINITY || k1 == Double.NEGATIVE_INFINITY) {
				throw new Exception();
			}
			double b1 = start1[1] - k1*start1[0];
			
			double k2 = (double)(end2[1] - start2[1])/(double)(end2[0] - start2[0]);
			double b2 = start2[1] - k2*start2[0];
			
			if(k1 == k2 && b1==b2) { //重合但不一定相交
				if(Math.min(start2[0],end2[0]) >= Math.min(start1[0], end1[0]) && Math.min(start2[0],end2[0]) <= Math.max(start1[0], end1[0])) {
					return new double[] {Math.min(start2[0],end2[0]), Math.min(start2[0],end2[0])*k1+b1};
				} else if(Math.max(start2[0],end2[0]) >= Math.min(start1[0], end1[0]) && Math.max(start2[0],end2[0]) <= Math.max(start1[0], end1[0])) {
					return new double[] {Math.min(start1[0],end1[0]), Math.min(start1[0],end1[0])*k1+b1};
				} else {
					return new double[] {};
				}
			}
			else if (k1 == k2 && b1 != b2) //平行
			{
				return new double[] {};
			} else { //既不平行也不重合
				x_res = (b1-b2)/(k2-k1);
				y_res = k1*x_res + b1;
				System.out.println(x_res + " " + y_res);
				if(x_res >= Math.min(start1[0], end1[0]) && x_res <= Math.max(start1[0], end1[0]) && y_res <= Math.max(start2[1], end2[1]) && y_res >= Math.min(start2[1], end2[1])) { //有交点
					return new double[] {x_res, y_res};
				} else {
					return new double[] {};
				}
				
			}
			
		} catch (Exception e) { //k1为无穷大 第一条线段为x=start1[0]
//			System.out.println("k1true");
			x_res = start1[0];
			
			try { //可能有交点
				double k2 = (double)(end2[1] - start2[1])/(double)(end2[0] - start2[0]);
				if(k2 == Double.POSITIVE_INFINITY || k2 == Double.NEGATIVE_INFINITY) {
					throw new Exception();
				}
				
				double b2 = start2[1] - k2*start2[0];

				if(x_res >= Math.min(start1[0], end1[0]) && x_res <= Math.max(start1[0], end1[0])) { //有交点
					y_res = k2*x_res + b2;
					return new double[] {x_res, y_res};
				} else { //无交点
					return new double[] {};
				}
				
			} catch (Exception e2) { //两条线段都垂直于x轴
				if(x_res == start2[0]) { //重合
//					System.out.println(true);
//					System.out.println(Math.min(start2[1],end2[1]));
					if(Math.min(start2[1],end2[1]) >= Math.min(start1[1], end1[1]) && Math.min(start2[1],end2[1]) <= Math.max(start1[1], end1[1])) {
						return new double[] {x_res, Math.min(start2[1],end2[1])};
					} else if(Math.max(start2[1],end2[1]) >= Math.min(start1[1], end1[1]) && Math.max(start2[1],end2[1]) <= Math.max(start1[1], end1[1])) {
						return new double[] {x_res, Math.min(start1[1],end1[1])};
					} else {
						return new double[] {};
					}
				} else { //没有交点
					return new double[] {};
				}
			}
		}
	
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值