N个点求最大斜率
面试题:
平面上N个点,每两个点都确定一条直线,求出斜率最大的那条直线所通过的两个点(斜率不存在的情况不考虑)。时间效率越高越好。
分析:
3个点A,B,C,把它们的按x坐标排序。
假设排序后的顺序是ABC,那么有两种情况:
1.ABC共线,则k(AB)=k(BC)=k(AC)
2.ABC不共线,则ABC将形成一个三角形,那么k(AC)<max(k(AB), k(BC))
其中k()表示求斜率。
所以程序的基本步骤就是:
1.把N个点按x坐标排序。
2.遍历,求相邻的两个点的斜率,找最大值。
复杂度Nlog(N)。
先把这些点按x坐标从小到大排序,斜率最大的两点必然是挨一起的两个点,所以排序O(n* lg n),遍历一次O(n)就够了。
代码:
#include <iostream> #include <vector> #include <algorithm> #include <cfloat> using namespace std; class Point { public: Point(float x, float y):x(x),y(y){} public: float x; float y; }; bool less_first(const Point &pt1, const Point &pt2) { return pt1.x < pt2.x; } void printPts(const vector<Point> pts) { for(int i=0; i<pts.size(); i++) { cout << "point " << i << ": (" <<pts[i].x << "," << pts[i].y << ")"<< endl; } } float findMaxK(const vector<Point> &pts, int &index) { float maxK = FLT_MIN; for(int i=1; i<pts.size(); i++) { Point pt1 = pts[i-1]; Point pt2 = pts[i]; float k = (pt2.y-pt1.y)/(pt2.x-pt1.x); // 斜率(point[i-1],point[i])) if(maxK < k) { maxK = k; index = i; } } return maxK; } int main() { vector<Point> points; points.push_back(Point(2.3, 3.5)); points.push_back(Point(7.2, 3.5)); points.push_back(Point(5.5, 6.4)); points.push_back(Point(2.3, 1.3)); points.push_back(Point(6.6, 8.1)); points.push_back(Point(1.7, 6.0)); points.push_back(Point(4.8, 5.4)); points.push_back(Point(0.7, 7.5)); //printPts(points); // N个点按x排序 sort(points.begin(), points.end(), less_first); printPts(points); int index; float maxK = findMaxK(points, index); cout << "max k: " << maxK << " generated by point " << index - 1 << " and point " << index << "." << endl; return 0; }