题目描述
给出一系列平面直角坐标系中的整数点 (x, y),从 0 开始编号,第 i 个点的编号为 i。不存在任意两点的横坐标相同,找出能构成的最大斜率直线的两个点的编号 (a,b)。如果有多个这样的点对,返回字典序最小的点对。
思路点拨
无论多少个点都可以任意选三个点组成一个三角形,那么斜率最大的边肯定不是通过相邻的两个点,以此可知斜率最大的直线一点是由两个相邻的点画出的。
考点分析
本题主要考察观察能力与快速排序,先将这些点按 x 排序,之后相邻两点中斜率最大的即为答案,时间复杂度 O(nlogn)。
参考程序
https://www.jiuzhang.com/solution/maximum-slope-straight-line/
/**
* 本参考程序来自九章算法,由 @华助教 提供。版权所有,转发请注明出处。
* - 九章算法致力于帮助更多中国人找到好的工作,教师团队均来自硅谷和国内的一线大公司在职工程师。
* - 现有的面试培训课程包括:九章算法班,系统设计班,算法强化班,Java入门与基础算法班,Android 项目实战班,
* - Big Data 项目实战班,算法面试高频题班, 动态规划专题班
* - 更多详情请见官方网站:http://www.jiuzhang.com/?source=code
*/
public class Solution {
/**
* @param points: The points set
* @return: Return the point pair
*/
class IndexPoint {
Point point;
int index;
IndexPoint() {
point = new Point();
index = 0;
}
IndexPoint(Point p, int i) {
point = p;
index = i;
}
}
public List<Integer> getPoints(Point[] points) {
int n = points.length;
IndexPoint[] p = new IndexPoint[n];
for (int i = 0; i < n; i++) {
p[i] = new IndexPoint(points[i], i);
}
Comparator cmp = new MyComparator();
Arrays.sort(p, cmp);
Integer[] a = new Integer[2];
a[0] = 0;
a[1] = 1;
for (int i = 1; i < n - 1; i++) {
long fct1 = (long) (p[i + 1].point.x - p[i].point.x) * (p[a[1]].point.y - p[a[0]].point.y);
long fct2 = (long) (p[a[1]].point.x - p[a[0]].point.x) * (p[i + 1].point.y - p[i].point.y);
if (fct1 < fct2 || fct1 == fct2 && p[i].index < a[0] && p[i + 1].index < a[0]) {
a[0] = i;
a[1] = i + 1;
}
}
a[0] = p[a[0]].index;
a[1] = p[a[1]].index;
if (a[0] > a[1]) {
int t = a[0];
a[0] = a[1];
a[1] = t;
}
List<Integer> ans = new ArrayList<>();
ans.add(a[0]);
ans.add(a[1]);
return (ans);
}
class MyComparator implements Comparator<IndexPoint> {
@Override
public int compare(IndexPoint o1, IndexPoint o2) {
if (o1.point.x < o2.point.x) {
return (-1);
} else if (o1.point.x > o2.point.x) {
return (1);
} else if (o1.index < o2.index) {
return (-1);
} else {
return (1);
}
}
}
}