题解 | #直线上的牛#
直线上的牛
https://www.nowcoder.com/practice/58ff4047d6194d2ca4d80869f53fa6ec
该题用例不够,若能链接两条平行线的情况用例中没有体现,但我们练习需要注意到
eg:用例[[1,1],[1,2],[2,1],[2,2]]
我们一定是以斜率作为Map的Key 但value不能只存数量,还应考虑到同斜率的多线条情况
顾value也用Map保存,key存该线条的首点,value为以该点链接出来的k斜率线条所过点
判断用双循环,组成一个第二层循环的开始为第一层循环的 位置+1,这样就足矣保证每个点相互之间都链接到了
import java.util.*;
public class Solution {
int max = 0;
// 斜率所对应的首点,和其所对应的列表
Map<Double, Map<Integer[], List<Integer[]>>> kMap = new HashMap<>();
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param points int整型二维数组
* @return int整型
*/
public int maxPoints (int[][] points) {
for (int i = 0; i < points.length; i ++) {
for (int h = i + 1; h < points.length; h ++) {
// 以上是第一个点
// 计算和另外一个数组成的斜率
addPoint(getK(points[i], points[h]), points[i], points[h]);
}
}
return max;
}
// 将点追加到斜率里
public void addPoint(double k, int[] num1, int[] num2) {
// 该斜率对于的多个链表 key为首点
Map<Integer[], List<Integer[]>> kMapList = kMap.get(k) ;
List<Integer[]> listPoint;
if (kMapList == null) {
kMapList = new HashMap<>();
listPoint = new ArrayList<>();
listPoint.add(creatInteger(num1));
listPoint.add(creatInteger(num2));
kMapList.put(creatInteger(num1), listPoint);
kMap.put(k, kMapList);
max = 2;
return;
} else {
// 判断当前点和首点斜率是否相同,若相同则放进去
for(Integer[] value : kMapList.keySet()) {
if (getK(num1, new int[]{value[0], value[1]}) == k) {
listPoint = kMapList.get(value);
// 判断与数字是否组成一个斜率
if (getK(num1, new int[] {listPoint.get(0)[0], listPoint.get(0)[1]}) != k) {
return;
}
if (!hasNum(listPoint, num1)) {
listPoint.add(new Integer[] {num1[0], num1[1] });
}
if (!hasNum(listPoint, num2)) {
listPoint.add(new Integer[] {num2[0], num2[1] });
}
kMapList.put(value, listPoint);
kMap.put(k, kMapList);
max = max > listPoint.size() ? max : listPoint.size();
System.out.print("max" + max + " k" + k);
return;
}
}
listPoint = new ArrayList<>();
listPoint.add(creatInteger(num1));
listPoint.add(creatInteger(num2));
kMapList.put(creatInteger(num1), listPoint);
kMap.put(k, kMapList);
max = max > listPoint.size() ? max : listPoint.size();
}
return;
}
// 获取斜率
public double getK (int[] num1, int[] num2) {
// 两则在同一x上
double k;
if (num2[1] - num1[1] == 0) {
k = -1000000000; // 随便选的值,却保其为水平线
System.out.print(" ---- [[" + num1[0] + "," + num1[1] + "],[" + num2[0] + "," + num2[1] + "]]");
} else {
k = (num2[0] - num1[0] ) / (num2[1] - num1[1]);
}
return k;
}
// 判断斜率所对应的队列里是否有该值
public boolean hasNum(List<Integer[]> listPoint, int[] num) {
for (int i = 0; i < listPoint.size(); i++) {
Integer[] value = listPoint.get(i);
if (value[0] == num[0] && value[1] == num[1]) {
return true;
}
}
return false;
}
public Integer[] creatInteger(int[] num) {
return new Integer[] {num[0], num[1]};
}
}