您的位置:首页 > 编程语言 > PHP开发

【PHP解法==LeetCode查找类型问题3(距离计算)】447.回旋镖的数量 && 149.直线上最多的点数(hard)

2019-01-25 16:04 531 查看

447.回旋镖的数量

给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 

(i, j, k)
 ,其中 
i
 和 
j
 之间的距离和 
i
 和 
k
 之间的距离相等(需要考虑元组的顺序)。

找到所有回旋镖的数量。你可以假设 n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中。

示例:

输入:[[0,0],[1,0],[2,0]]
输出:2
解释:两个回旋镖为 [[1,0],[0,0],[2,0]][[1,0],[2,0],[0,0]]
[code]class Solution {
function numberOfBoomerangs($points) {
//查找数
$len = count($points);
$num = 0;
//取一个固定点,检测该固定点到其他点的距离
for($i = 0;$i<$len;++$i){
$distance = [];
for($j = 0;$j<$len;++$j){
if($j != $i){
$key = $this->dis($points[$i],$points[$j]);
if(isset($distance[$key])){
$distance[$key]++;
}else{
$distance[$key] = 1;
}
//echo 'i';print_r($points[$i]);
//echo 'j';print_r($points[$j]);
//echo 'dis',dis($points[$i],$points[$j]),'<br>';
}
}
//print_r($distance);
//取得的结果,两两成一对,每一对可以有两种可能,所以进行排列组合排列组合An(n-1)
foreach ($distance as $v)
if($v>1)
$num += $v*($v-1);
}
return $num;
}
function dis($a ,$b){
//勾股定理,不开根号,防止出现浮点数
return ($a[0]-$b[0])*($a[0]-$b[0]) + ($a[1]-$b[1])*($a[1]-$b[1]);
}
}

149.直线上最多的点数(hard)

给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。

示例 1:

输入: [[1,1],[2,2],[3,3]]
输出: 3
解释:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4

示例 2:

输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4
解释:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6

该题与上题结题类似,均是求坐标上的点,但此时需要求在一直线上

要考虑有三种情况:平行于x轴,平行于y轴,坐标点重复情况

其他均可用斜率表示,用xy的比值做哈希查找表

[code]/**
* Definition for a point.
* class Point(
*     public $x = 0;
*     public $y = 0;
*     function __construct(int $x = 0, int $y = 0) {
*         $this->x = $x;
*         $this->y = $y;
*     }
* )
*/
class Solution {
function maxPoints($points) {
//[[1,1],[2,2],[3,3]]
//[[2,3],[3,3],[-5,3]]
//[[1,1],[1,1],[2,2],[2,2]]
//[[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
//查找数
$len = count($points);
$max = 0;//记录在同一直线点数最多的数
for($i = 0;$i<$len;++$i){
$distance = [0];//斜率比值哈希表
$x = $y = 0;//记录平行点
$common = 1;//记录重复点
for($j = 0;$j<$len;++$j){
if($j != $i){
$key = $this->dis($points[$i],$points[$j]);
if($key == 'x') $x++;
elseif($key == 'y') $y++;
elseif($key == 'same') $common++;
else{
if(isset($distance[$key]))
$distance[$key]++;
else
$distance[$key] = 1;
}
}
}
$num = max($x,$y,max($distance)) + $common;
if($num > $max) $max = $num;
//已经包含全部记录,无需继续检索
if($num == $len) break;
}
return $max;
}
//求斜率比值/平行点/重复点
function dis($a,$b){
$x = $a->x - $b->x;
$y = $a->y - $b->y;
if($x == 0 && $y==0) return 'same';//重复点
if( $x == 0 ) return 'x';//平行于x轴
if( $y == 0 ) return 'y';//平行于y轴
$div = $this->max_divisor($x,$y);
return $x/$div.':'.$y/$div;
}
//求最大公约数
function max_divisor($a, $b){
if($b==0)
return $a;
else
return $this->max_divisor($b,($a%$b));
}
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: