LeetCode lcci 16.03 交点

Posted Simon_X

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode lcci 16.03 交点相关的知识,希望对你有一定的参考价值。

原本我想使用无限叠if-else的方式估计能解决, 但这样总归是不够优雅。

使用点斜式在斜率上可能存在问题, 为了少写判断, 使用一般式描述直线。并且将坐标带入一般式就能直观判断点与直线的位置关系, 以此判断线段的位置关系

完成关系判断后, 剩下的事就相当于求直线交点, 直接解方程又得判断条件, 不行, 这很麻烦...

搜索? 二分x轴或y轴?同时考虑xy又得加条件, 太累了

既然给定目标与样本...等等, 机器学习? 线性回归?

反向传播...不对, 题目的条件明确(样本完全), 可以直接求最优解(xy)

接下来就是转化成矩阵形式

[egin{cases} a_1x + b_1y+c_1 = 0 a_2x + b_2y+c_2 = 0 end{cases} ]

[egin{cases} a_1x + b_1y = -c_1 a_2x + b_2y = -c_2 end{cases} ]

[egin{pmatrix} x&y end{pmatrix} egin{pmatrix} a_1&a_2_1&b_2 end{pmatrix} = egin{pmatrix} -c_1&-c_2 end{pmatrix} \begin{pmatrix} x&y end{pmatrix} egin{pmatrix} a_1&a_2_1&b_2 end{pmatrix} egin{pmatrix} a_1&a_2_1&b_2 end{pmatrix}^{-1} = egin{pmatrix} -c_1&-c_2 end{pmatrix} egin{pmatrix} a_1&a_2_1&b_2 end{pmatrix}^{-1} \begin{pmatrix} x&y end{pmatrix} = egin{pmatrix} -c_1&-c_2 end{pmatrix} egin{pmatrix} a_1&a_2_1&b_2 end{pmatrix}^{-1} ]

接下来就是二阶矩阵求逆矩阵

[egin{pmatrix} a&bc&d end{pmatrix}^{-1} = frac{1}{det} egin{pmatrix} d&-b-c&a end{pmatrix} \begin{pmatrix} a&bc&d end{pmatrix}^{-1} = frac{1}{ad - bc} egin{pmatrix} d&-b-c&a end{pmatrix} ]

由于在一般式阶段已经可以完成一些判断, 过滤特殊情况, 所以行列式det已经不为0, 直接计算逆矩阵带入后就能得到交点(x, y)

_(:з」∠)_

如果从行列式角度直接讨论无解/多解/唯一解, 似乎需要线性变换, 太麻烦...不管了

C艹

class Solution {
public:
    struct pit {
        int x, y;
        
        bool operator<(const pit &b) const {
            if (x != b.x) return x < b.x;
            return y < b.y;
        }
    };
    
    vector<double> intersection(vector<int>& start1, vector<int>& end1, vector<int>& start2, vector<int>& end2) {
        if (std::max(start1[0], end1[0]) < std::min(start2[0], end2[0])) return {};
        if (std::max(start1[1], end1[1]) < std::min(start2[1], end2[1])) return {};
        
        int a1 = start1[1] - end1[1], b1 = end1[0] - start1[0];
        int c1 = -(a1*end1[0] + b1*end1[1]);
        
        int v1 = a1*start2[0] + b1*start2[1] + c1;
        int v2 = a1*end2[0] + b1*end2[1] + c1;
        if (v1*v2 > 0) return {};
        
        if (v1 == v2) {
            pit ary[4] = {
                {start1[0], start1[1]}, {end1[0], end1[1]},
                {start2[0], start2[1]}, {end2[0], end2[1]},
            };
            std::sort(ary, ary + 4);
            return {double(ary[1].x), double(ary[1].y)};
        }
        
        int a2 = start2[1] - end2[1], b2 = end2[0] - start2[0];
        int c2 = -(a2*end2[0] + b2*end2[1]);
        
        v1 = a2*start1[0] + b2*start1[1] + c2;
        v2 = a2*end1[0] + b2*end1[1] + c2;
        if (v1*v2 > 0) return {};
        
        double detL = a1*b2 - a2*b1;
        double L[2][2] = {
            {b2/detL, -a2/detL},
            {-b1/detL, a1/detL},
        };
        double optX = -c1*L[0][0] + -c2*L[1][0];
        double optY = -c1*L[0][1] + -c2*L[1][1];
        return {optX, optY};
    }
};

以上是关于LeetCode lcci 16.03 交点的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode.面试题 01.08. Zero Matrix LCCI题解

LeetCode 面试题 16.03. 交点

边做算法边学go语言之程序员面试金典面试题 01.06. 字符串压缩

[leetcode]160. Intersection of Two Linked Lists两链表交点

mod_zeropush 在 ejabberd 16.03 中停止工作

sh 安装开发人员环境Ubuntu Xenial(16.03)