LeetCode 面试题 16.03. 交点

题目描述:

给定两条线段(表示为起点start = {X1, Y1}和终点end = {X2, Y2}),如果它们有交点,请计算其交点,没有交点则返回空值。

要求浮点型误差不超过10^-6。若有多个交点(线段重叠)则返回 X 值最小的点,X 坐标相同则返回 Y 值最小的点。

就是要分类讨论一下,要注意的是在判断两条线段是否相交时,不要使用浮点运算,可能会造成判断错误。

class Solution {
public:
    vector<double> intersection(vector<int>& start1, vector<int>& end1, vector<int>& start2, vector<int>& end2) {
        //设置别称,方便写代码
        const int& x1 = start1[0];
        const int& y1 = start1[1];
        const int& x2 = end1[0];
        const int& y2 = end1[1];
        const int& x3 = start2[0];
        const int& y3 = start2[1];
        const int& x4 = end2[0];
        const int& y4 = end2[1];

        //计算两条直线的系数
        int A1, B1, C1, A2, B2, C2;
        A1 = y1 - y2;
        B1 = x2 - x1;
        C1 = y2 * x1 - y1 * x2;
        A2 = y3 - y4;
        B2 = x4 - x3;
        C2 = y4 * x3 - y3 * x4;

        vector<double> res;
        if ((y2-y1)*(x4-x3) != (x2-x1)*(y4-y3)) {//如果斜率不同,这种情况不可能重合
            //测试是否相交
            if (A1 * x3 + B1 * y3 + C1 == 0) { res.push_back(x3); res.push_back(y3); return res;}
            if (A1 * x4 + B1 * y4 + C1 == 0) { res.push_back(x4); res.push_back(y4); return res;}
            if (A2 * x1 + B2 * y1 + C2 == 0) { res.push_back(x1); res.push_back(y1); return res;}
            if (A2 * x2 + B2 * y2 + C2 == 0) { res.push_back(x2); res.push_back(y2); return res;}

            if ((A1 * x3 + B1 * y3 + C1) * (A1 * x4 + B1 * y4 + C1) < 0
                && (A2 * x1 + B2 * y1 + C2) * (A2 * x2 + B2 * y2 + C2) < 0) {
                res.push_back(B2*C1 - B1*C2);
                res.push_back(A1*C2 - A2*C1);
                res[0] /= A2 * B1 - A1 * B2;
                res[1] /= A2 * B1 - A1 * B2;
                return res;
            }
            else return res;
        }
        else {//斜率相同,这种时候有可能重合,也有可能平行
            if (A1 * x3 + B1 * y3 + C1 == 0) {//两条直线是重合的
                if (x1 != x2){//不垂直y轴
                    if (max(x1, x2) >= min(x3, x4) && min(x3,x4) >= min(x1,x2)) {
                        if (x3 < x4) return vector<double> {double(x3), double(y3)};
                        else return vector<double> {double(x4), double(y4)};
                    }
                    else if (max(x3, x4) >= min(x1, x2) && min(x3, x4) <= min(x1, x2)) {
                        if (x1 < x2) return vector<double> {double(x1), double(y1)};
                        else return vector<double> {double(x2), double(y2)};
                    }
                    else {
                        return res;
                    }
                }
                else {//垂直y轴
                    if (max(y1, y2) >= min(y3, y4) && min(y3, y4) >= min(y1, y2)) {
                        if (y3 < y4) return vector<double> {double(x3), double(y3)};
                        else return vector<double> {double(x4), double(y4)};
                    }
                    else if (max(y3, y4) >= min(y1, y2) && min(y3, y4) <= min(y1, y2)) {
                        if (y1 < y2) return vector<double> {double(x1), double(y1)};
                        else return vector<double> {double(x2), double(y2)};
                    }
                    else {
                        return res;
                    }
                }

            }
            else {//平行
                return res;
            }
        }
    }
};

原文地址:https://www.cnblogs.com/airfy/p/12687934.html

时间: 2024-10-14 07:51:42

LeetCode 面试题 16.03. 交点的相关文章

leetcode-面试题16.03交点

题目描述: 方法: class Solution: def intersection(self, start1, end1, start2, end2): x1, y1, x2, y2, x3, y3, x4, y4 = *start1, *end1, *start2, *end2 det = lambda a, b, c, d: a * d - b * c d = det(x1 - x2, x4 - x3, y1 - y2, y4 - y3) p = det(x4 - x2, x4 - x3,

菜鸟系列 Golang 实战 Leetcode —— 面试题16. 数值的整数次方

实现函数double Power(double base, int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. ? 示例 1: 输入: 2.00000, 10 输出: 1024.00000 示例?2: 输入: 2.10000, 3 输出: 9.26100 示例?3: 输入: 2.00000, -2 输出: 0.25000 解释: 2-2 = 1/22 = 1/4 = 0.25 ? 说明: -100.0 <?x?< 100.0 n?是 32 位

LeetCode 面试题62. 圆圈中最后剩下的数字

我的LeetCode:https://leetcode-cn.com/u/ituring/ 我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii LeetCode 面试题62. 圆圈中最后剩下的数字 题目 0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字

Head FIRST HTML &amp; CSS 16/03/17

css基本: font-famliy font-size font-style text-decoration color background-color ... 技巧: 在body选择器内先定义父类元素,给子类继承,便于管理 font-famliy后的选项其实是一个待选的优先列表 font-size 在body内最好先定义small,medium,large...子类通过200%,1.2em改变 font-style控制斜体,和<em>本质不同 italic text-decoration

面试题16:数值的整数次方

// 面试题16:数值的整数次方 // 题目:实现函数double Power(double base, int exponent),求base的exponent // 次方.不得使用库函数,同时不需要考虑大数问题. 解题思路: 解题并不难,重要的是要考虑到输入的各种情况,并且有相应的处理. double和int都是可以取负数和0的,如果base取0,exponent<0,结果显然是不存在的. base取0,exponent取非负,直接返回1就可以了. 其他情况,正常运算就好,要注意如果expo

C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介

目录 为什么要刷LeetCode 刷LeetCode有哪些好处? LeetCode vs 传统的 OJ LeetCode刷题时的心态建设 C#如何刷遍LeetCode 选项1: VS本地Debug + 在线验证后提交 选项2: VS Code本地Debug + 在 LeetCode 插件中验证和提交 为什么要刷LeetCode 大家都知道,很多对算法要求高一点的软件公司,比如美国的FLAGM (Facebook.LinkedIn.Amazon/Apple.Google.Microsoft),或国

C#刷遍Leetcode面试题系列连载(2): No.38 - 报数

目录 前言 题目描述 相关话题 相似题目 解题思路: 运行结果: 代码要点: 参考资料: 文末彩蛋 前言 前文传送门: C# 刷遍 Leetcode 面试题系列连载(1) - 入门与工具简介 上篇文章中我们主要科普了刷 LeetCode 对大家的作用,今天咱们就正式进行 LeetCode 算法题分析.很多人都知道计算机中有种思想叫 递归,相应地也出现了很多算法.解决递归问题的要点有如下几个: 找出递归的关系 比如,给个数列 f(n),常见的递归关系是后面的项 f(n+1)与前面几项之间的关系,比

C#刷遍Leetcode面试题系列连载(5):No.593 - 有效的正方形

上一篇 LeetCode 面试题中,我们分析了一道难度为 Easy 的数学题 - 自除数,提供了两种方法.今天我们来分析一道难度为 Medium 的面试题. 系列教程索引 传送门:https://enjoy233.cnblogs.com/articles/leetcode_csharp_index.html C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介 C#刷遍Leetcode面试题系列连载(2): No.38 - 报数 C# 刷遍 Leetcode 面试题系列连载(3):

LeetCode | 面试题59 - II. 队列的最大值【Python】

LeetCode 面试题59 - II. 队列的最大值[Medium][Python][队列] 问题 力扣 请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value.push_back 和 pop_front 的均摊时间复杂度都是O(1). 若队列为空,pop_front 和 max_value 需要返回 -1 示例 1: 输入: ["MaxQueue","push_back","push_back",&quo