您的位置:首页 > 其它

Max Points on a Line

2014-08-13 15:42 169 查看
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.



最简单直接方法就是把某一点固定,然后寻找所有到剩余点的斜率,两次循环之后就能得到题目所要求。

直线我们很快想到斜率来表示,利用斜率最需要注意斜率无穷大的情况,需要拿出来单独进行考虑。其实我觉得这个题目有一些问题就是:我们使用Double 来表示斜率,但是小数无法进行精确比较!!但是LeetCode上测试案例没有这么极端,不考虑这个问题也能AC。

package Max_Points_on_a_Line;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class Solution {

	public static void main(String[] args) {
		Solution s = new Solution();
		Point arr[] = {  new Point(-8, -582),
				 new Point(-9, -651), new Point(9, 591) };
		
		System.out.println(s.maxPoints(arr));
	}

	public int maxPoints(Point[] points) {

		if (points.length < 2) {
			return points.length;
		}
		int maxNum = 0;
		
		Map<Double, Integer> mp = new TreeMap<>();
		mp.clear();
		for (int i = 0; i < points.length; i++) {
			//Important : 每次需要进行重置!!! 
			int duplicated = 1;
			mp.clear();
			// 斜率为无穷大的情况 
			mp.put(Double.MAX_VALUE, 0);
			for (int j = 0; j < points.length; j++) {
				if (i == j)
					continue;
				//记录有多少重复的点。
				if ((points[i].x == points[j].x)
						&& (points[i].y == points[j].y)) {
					duplicated++;
					continue;
				}
				double k = points[i].x == points[j].x ? Double.MAX_VALUE
						: (double)  (points[i].y - points[j].y)/((points[i].x - points[j].x)) ;
				if (!mp.containsKey(k)) {
					mp.put(k, 1);
				} else {
					mp.put(k, mp.get(k) + 1);
				}

			}
			
			Set<Map.Entry<Double, Integer>> set = mp.entrySet();
			Iterator<Map.Entry<Double, Integer>> it = set.iterator();
			for (; it.hasNext();) {
				 Map.Entry<Double, Integer> entry = it.next();  
				 
				if (entry.getValue()+ duplicated > maxNum) {
					maxNum = entry.getValue() + duplicated;
				}
			}
			
		}
		return maxNum;
	}

}

class Point {
	int x;
	int y;

	Point() {
		x = 0;
		y = 0;
	}

	Point(int a, int b) {
		x = a;
		y = b;
	}
}


这里需要注意几点:

1. 计算斜率公式:(double) (points[i].y - points[j].y)/((points[i].x - points[j].x)) 一定不能为 (double) ( (points[i].y - points[j].y)/((points[i].x - points[j].x))) 第二个式子为两个整数相除结果为整数然后再强制转型,而第一个就是先把第一个数转成double
然后再进行除法。

2. 注意

if (points.length < 2) {
			return points.length;
		}

测试案例中必然将包含数组为空的情况。

3. 我个人觉得这个最好方法还是不用斜率去判断是否在一条直线上,而是 利用公式 y1/x1 ?== y2/x2 把除法变成乘法来判断,这样就避免浮点数相等判断。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: