还记得高中的向量吗?leetcode 335. Self Crossing(判断线段相交)
传统解法
题目来自 leetcode 335. Self Crossing。
题意非常简单,有一个点,一开始位于 (0, 0) 位置,然后有规律地往上,左,下,右方向移动一定的距离,判断是否会相交(self crossing)。
一个很容易想到的方案就是求出所有线段,然后用 O(n^2) 的时间复杂度两两判断线段是否相交,而线段相交的判断,可以列个二元一次方程求解(交点)。这个解法非常容易想到,但是实际操作起来比较复杂,接下去介绍利用向量的解法。
向量解法
简单回顾下向量,具体的自行谷歌。向量就是一条有向线段,这里要用到的是向量的 叉乘。(还有个类似的概念叫做 点积)
叉乘公式:

而因为 p1 X p2 = | a | * | b | * sin α,后者又是平行四边形的面积公式,所以可以用叉乘来求解平行四边形的面积(同理可以求解三角形的面积)。PS:如果给出三个点坐标,求解三角形面积的话,最好用叉乘来做,这样更精确,而不是海伦公式。

向量叉乘还能判断 p0p1 和 p0p2 两个向量, 对于 p0 点而言,p0p1 是位于 p0p2 顺时针方向,还是逆时针方向。

我们回到判断线段相交,两线段相交有如下两种可能。

对于第一种情况,我们可以判断 p1, p2 两点分别位于线段 p3p4 两边,同时满足 p3, p4 两点分别位于线段 p1p2 两边。如何判断?以判断 p1,p2 是否位于线段 p3p4 两边为例,求解叉乘 p3p1 X p3p4,以及 p3p2 X p3p4,如果符合条件,两值必是一正一负。对于第二种情况,因为共线,所以叉乘结果为 0,但是叉乘结果为 0 只能保证共线,并不能保证相交,所以还需要进行如下的判断。

这样解法就呼之欲出了,贡献个判断线段相交的模板:
/**
* @param {object} a
* @param {object} b
* @return {boolean}
* a, b 表示两条线段。
* (a.x1, a.y1), (a.x2, a.y2) 分别表示线段 a 两个端点; b 类似
*/
function f(a, b) {
function online(a, b, c) {
if (a.x >= Math.min(b.x, c.x) && a.x <= Math.max(b.x, c.x) && a.y >= Math.min(b.y, c.y) && a.y <= Math.max(b.y, c.y))
return true;
return false;
}
var n1, n2, n3, n4;
n1 = (a.x1 - b.x2) * (b.y1 - b.y2) - (a.y1 - b.y2) * (b.x1 - b.x2);
n2 = (a.x2 - b.x2) * (b.y1 - b.y2) - (a.y2 - b.y2) * (b.x1 - b.x2);
n3 = (b.x1 - a.x2) * (a.y1 - a.y2) - (b.y1 - a.y2) * (a.x1 - a.x2);
n4 = (b.x2 - a.x2) * (a.y1 - a.y2) - (b.y2 - a.y2) * (a.x1 - a.x2);
if (n1 * n2 < 0 && n3 * n4 < 0)
return 1;
var p1 = {x: a.x1, y: a.y1};
var p2 = {x: a.x2, y: a.y2};
var p3 = {x: b.x1, y: b.y1};
var p4 = {x: b.x2, y: b.y2};
if (n1 === 0 && online(p1, p3, p4))
return 1;
if (n2 === 0 && online(p2, p3, p4))
return 1;
if (n3 === 0 && online(p3, p1, p2))
return 1;
if (n4 === 0 && online(p4, p1, p2))
return 1;
return 0;
}
本题完整代码详见 https://github.com/hanzichi/leetcode/tree/master/Algorithms/Self%20Crossing,求 star, 求 fork,求 follow
还记得高中的向量吗?leetcode 335. Self Crossing(判断线段相交)的更多相关文章
- [leetcode]335. Self Crossing
You are given an array x of n positive numbers. You start at point (,) and moves x[] metres to the n ...
- nyoj-1016-德莱联盟(向量叉乘判断线段相交)
叉乘的坐标表示: A(X1,Y1), B(X2, Y2), C(XC,YC), D(XD, YD);AB = (X2-X1, Y2-Y1);CD = (XD-XC, YD-YC); 向量AB,CD的叉 ...
- c#静态构造函数 与 构造函数 你是否还记得?
构造函数这个概念,在我们刚开始学习编程语言的时候,就被老师一遍一遍的教着.亲,现在你还记得静态构造函数的适用场景吗?如果没有,那么我们一起来复习一下吧. 静态构造函数是在构造函数方法前面添加了stat ...
- 《C#编程风格》还记得多少
开始实习之后,才发现自己是多么地菜.还有好多东西还要去学习. 公司很好,还可以帮你买书.有一天随口问了一下上司D,代码规范上面有什么要求.然后D在Amazon上面找到了这本书<C#编程风格(Th ...
- 【编程之外】还记得曾经给'大学导师'写过的报告嘛 --> 前方高能
写在前面 本文不是讲技术的,也没什么代码可看 本文不是讲技术的,也没什么代码可看 本文不是讲技术的,也没什么代码可看 还记得我们曾经给我们大学''导师''写过的报告嘛? 大学他愿意在凌晨6点向你询问近 ...
- c#静态构造函数 与 构造函数 你是否还记得?(转载)
构造函数这个概念,在我们刚开始学习编程语言的时候,就被老师一遍一遍的教着.亲,现在你还记得静态构造函数的适用场景吗?如果没有,那么我们一起来复习一下吧.静态构造函数是在构造函数方法前面添加了stati ...
- 你还记得当初为什么进入IT行业吗?
说到这个问题,小编相信不少童鞋开始忆往昔峥嵘岁月,那个少年为了心中的改变世界的理想,进入了这个行业,但是呢,有一群人画风就不一样了,他们进入IT行业,完全只是是因为.... 小时候广告看多了....: ...
- 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射
使用Code First建模自引用关系笔记 原文链接 一.Has方法: A.HasRequired(a => a.B); HasOptional:前者包含后者一个实例或者为null HasR ...
- .NET成人礼 | 还记得20年前一起拖过的控件吗?
本文是MVP Ediwang写的回忆一个80后的拖控件的感悟,与君共勉: 每一代人都有记忆里的味道.煤球炉.黑白电视机是属于父母的记忆.而“拖控件”式编程,启蒙了无数像我这样的80后(嗯,89也算80 ...
随机推荐
- Linux下python安装升级详细步骤 | Python2 升级 Python3
Linux下python升级步骤 Python2 ->Python3 多数情况下,系统自动的Python版本是2.x 或者yum直接安装的也是2.x 但是,现在多数情况下建议使用3.x 那么如 ...
- 2014.1.23 Discuz论坛迁移+VPS配置手记
虽说这也不是我第一次转移这个论坛了,但毕竟还是第一次自己配置VPS,写点东西记一下 一:关于VPS的配置 1.用TeamViewer连接服务器 这个VPS的IDC自己带有一个远程控制的页面,用浏览器打 ...
- 【hadoop】——压缩工具比较
文件压缩主要有两个好处,一是减少了存储文件所占空间,另一个就是为数据传输提速.在hadoop大数据的背景下,这两点尤为重要,那么我现在就先来了解下hadoop中的文件压缩. hadoop里支持很多种压 ...
- 关于 redis、memcache mongoDB 的对比
from:http://yang.u85.us/memcache_redis_mongodb.pdf 从以下几个维度,对 redis.memcache.mongoDB 做了对比.1.性能都比较高,性能 ...
- MD5 加密 java代码实现
package com.company.fjf; import java.security.MessageDigest; import java.security.NoSuchAlgorithmExc ...
- Sybase PowerDesign 导入数据库结构formSqlserver
采用Sybase PD 创建数据库设计是常见的方法,如果遇到链接数据源时,无法直接链接系统数据源,而且在Sybase PD中无法直接创建odbc数据源时, 可以到控制面板中创建数据源,一步步的网络上有 ...
- win7下Qt5使用mysql C++编程配置
先下载mysql的库文件链接:http://files.cnblogs.com/files/xiaobo-Linux/mysql.zip 把两个文件放入 Qt目录\Qt5.5.0\5.5\mingw4 ...
- vim linux SecureCRT vim颜色的设置
解决方法: 1.首先按照环境一的方法检查一下,如果环境一的情况不在进行第二步. 2.修改终端TERM这个环境变量: 1)export命令 临时生效 # echo $TERM xterm #如果结果 ...
- linux GD库安装
GD 安裝第一部需要做的是先要安裝 GD 到系統內,而安裝 GD 前需要安裝 jpeg-6b, libpng, zlib, freetype.以下是下载网址:GD 2.0.33jpeg-6blibpn ...
- 原来今天是感恩节-Linux基础继续&MySQL和PHP
hi 原来今天是感恩节.虽然一直没有过这个节日的习惯,但仅仅是听到感恩的消息,都能想到一幅幅画面.愿大家安好! 下午开题会议还是有所收获,悄悄的,就变向那个不喜欢自己的人了. 一.Linux基础(二) ...