【网易笔试题】战斗点

【网易笔试题】战斗点_第1张图片

解题思路

  • 重复的点没有必要去增加时间复杂度,
    先把point点简化成没有重复的新数组norepeatvalues以及记录每个新数组的成员point对应的重复次数repeatcounts数组;
  • 两个点可以确定一条直线,假设有一个起始点Point[i]和Point[j],它们俩相连的斜率为k,其它只要和它们相连的点必定与它们在同一条直线上;当然,斜率不存在的极端情况也是要考虑在内的,斜率不存在的点,它们点X坐标必定一样;
  • 由于norepeatvalues的长度和对应的点重复的个数数组repeatcounts长度不定,所以采用ArrayList数组;

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    static class Point {
        int x;
        int y;
        Point(int a, int b) {
            x = a;
            y = b;
        }
    }
    public static int maxPoints(Point[] points) {
        // Write your code here
        if (points == null) {
            return 0;
        }
        int maxcount = 0;
        int len = points.length;
        if (len < 2) {
            return len;
        }
        ArrayList norepeatvalues = new ArrayList();// 简化数组,记录不重复的数组
        ArrayList repeatcounts = new ArrayList();// 简化数组,记录norepeatvalues.get[i]的元素对应的在Point数组里面拥有的元素的重复个数
        for (int i = 0; i < len; i++) {
            int repeatcount = 0;
            boolean isrepeatnum = false;
            for (int m = 0; m < norepeatvalues.size(); m++) {
                // 判断这个Point是否是记录已经存在的
                if (norepeatvalues.get(m).x == points[i].x && points[i].y == norepeatvalues.get(m).y) {
                    isrepeatnum = true;
                    break;
                }
            }
            if (!isrepeatnum) {
                // 这个Point不是norepeatvalues记录已经存在的,则继续
                for (int j = i + 1; j < len; j++) {
                    if (points[i].x == points[j].x && points[i].y == points[j].y) {
                        // repeatcounts数组记录有多少个和points[i]相同的点
                        repeatcount++;
                    }
                }
                norepeatvalues.add(points[i]);
                repeatcounts.add(repeatcount);
            }
        }
        len = norepeatvalues.size();
        if (len == 1) {
            // 如果只有一个非重复元素
            return len + repeatcounts.get(0);
        }

        for (int i = 0; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                int tempcount = 2 + repeatcounts.get(i) + repeatcounts.get(j);
                float k = 0f;
                boolean hasK = true;// 判断斜率是否存在
                if (norepeatvalues.get(i).x == norepeatvalues.get(j).x) {
                    hasK = false;
                } else {
                    k = (float) (norepeatvalues.get(i).y - norepeatvalues.get(j).y)
                            / (norepeatvalues.get(i).x - norepeatvalues.get(j).x);
                }
                float b = norepeatvalues.get(i).y - k * norepeatvalues.get(i).x;
                for (int m = j + 1; m < len; m++) {
                    if (hasK) {
                        // 斜率存在
                        float curk = (float) (norepeatvalues.get(i).y - norepeatvalues.get(m).y)
                                / (norepeatvalues.get(i).x - norepeatvalues.get(m).x);
                        if (curk == k) {
                            tempcount = tempcount + repeatcounts.get(m) + 1;
                        }
                    } else {
                        // 斜率不存在
                        if (norepeatvalues.get(i).x == norepeatvalues.get(m).x) {
                            tempcount = tempcount + repeatcounts.get(m) + 1;
                        }
                    }
                }
                if (tempcount > maxcount) {
                    maxcount = tempcount;
                }
            }
        }
        return maxcount;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        Point[] data = new Point[n];
        for (int i = 0; i < n; i++) {
            data[i] = new Point(sc.nextInt(), sc.nextInt());
        }
        System.out.println(maxPoints(data));
    }
}

你可能感兴趣的:(网易笔试题)